package bjc.dicelang.neodice.die; import java.util.*; import java.util.function.*; import bjc.dicelang.neodice.*; import bjc.esodata.*; public class RerollDie implements Die { private final Die contained; private final Predicate condition; private final Function, SideType> chooser; private final Comparator comparer; private int limit = Integer.MAX_VALUE; private RerollDie( Comparator comparer, Die contained, Predicate condition, Function, SideType> chooser) { this.comparer = comparer; this.contained = contained; this.condition = condition; this.chooser = chooser; } private RerollDie( Comparator comparer, Die contained, Predicate condition, Function, SideType> chooser, int limit) { this(comparer, contained, condition, chooser); this.limit = limit; } @Override public SideType roll(Random rng) { SideType roll = contained.roll(rng); MinMaxList newRolls = new MinMaxList<>(comparer, roll); int rerollCount = 0; while (condition.test(roll) && rerollCount < limit) { roll = contained.roll(rng); newRolls.add(roll); rerollCount += 1; } return chooser.apply(newRolls); } public static > Die create( Die contained, Predicate condition, Function, Side> chooser) { return new RerollDie<>(Comparator.naturalOrder(), contained, condition, chooser); } public static > Die create( Die contained, Predicate condition, Function, Side> chooser, int limit) { return new RerollDie<>(Comparator.naturalOrder(), contained, condition, chooser, limit); } public static Die create( Comparator comparer, Die contained, Predicate condition, Function, Side> chooser) { return new RerollDie(comparer, contained, condition, chooser); } public static Die create( Comparator comparer, Die contained, Predicate condition, Function, Side> chooser, int limit) { return new RerollDie(comparer, contained, condition, chooser, limit); } }