package bjc.dicelang.dice; import java.util.LinkedList; import java.util.List; import java.util.function.Predicate; /** * An exploding die. * * Represents a die list that keeps getting another added die as long as a * condition is met. * * @author Ben Culkin */ public class ExplodingDice implements DieList { /* The source die to use. */ private final Die source; /* The conditions for exploding. */ private final Predicate explodeOn; private final String explodePattern; /* Whether or not to apply a -1 penalty to explosions. */ private final boolean explodePenetrates; /** * Create a new exploding die. * * @param src * The source die for exploding. * @param explode * The condition to explode on. */ public ExplodingDice(final Die src, final Predicate explode) { this(src, explode, null, false); } /** * Create a new exploding die that may penetrate. * * @param src * The source die for exploding. * @param explode * The condition to explode on. * @param penetrate * Whether or not for explosions to penetrate (-1 to * exploded die). */ public ExplodingDice(final Die src, final Predicate explode, final boolean penetrate) { this(src, explode, null, penetrate); } /** * Create a new exploding die that may penetrate. * * @param src * The source die for exploding. * @param explode * The condition to explode on. * @param penetrate * Whether or not for explosions to penetrate (-1 to * exploded die). * @param patt * The string the condition came from, for printing. */ public ExplodingDice(final Die src, final Predicate explode, final String patt, final boolean penetrate) { source = src; explodeOn = explode; explodePattern = patt; explodePenetrates = penetrate; } @Override public boolean canOptimize() { return false; } @Override public long[] optimize() { return new long[0]; } @Override public long[] roll() { final long res = source.roll(); long oldRes = res; final List resList = new LinkedList<>(); resList.add(res); while (explodeOn.test(oldRes)) { oldRes = source.rollSingle(); if (explodePenetrates) { oldRes -= 1; } resList.add(oldRes); } final long resArr[] = new long[resList.size()]; int i = 0; for(long rll : resList) { resArr[i] = rll; i += 1; } return resArr; } @Override public String toString() { String penString = explodePenetrates ? "p" : ""; String sourceString = source.toString(); if (explodePattern == null) { return String.format("%s%s!", sourceString, penString); } return String.format("%s%s!%s", sourceString, penString, explodePattern); } }