From b5c2fb1ed923d43412694729b4445a66fa9f47fc Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Sat, 21 Nov 2020 18:10:30 -0500 Subject: Restructure new die implementation --- dice/src/main/java/bjc/dicelang/neodice/Die.java | 111 +------ .../main/java/bjc/dicelang/neodice/DieFactory.java | 63 ---- .../main/java/bjc/dicelang/neodice/DiePool.java | 320 +-------------------- .../java/bjc/dicelang/neodice/DiePoolFactory.java | 82 ------ .../bjc/dicelang/neodice/die/PolyhedralDie.java | 46 +++ .../java/bjc/dicelang/neodice/die/RerollDie.java | 55 ++++ .../dicelang/neodice/diepool/DropFirstPool.java | 58 ++++ .../bjc/dicelang/neodice/diepool/DropLastPool.java | 58 ++++ .../dicelang/neodice/diepool/FilteredDiePool.java | 47 +++ .../bjc/dicelang/neodice/diepool/FixedDiePool.java | 65 +++++ .../dicelang/neodice/diepool/KeepFirstDiePool.java | 58 ++++ .../dicelang/neodice/diepool/KeepLastDiePool.java | 58 ++++ .../dicelang/neodice/diepool/SortedDiePool.java | 63 ++++ .../bjc/dicelang/neodice/diepool/TimesDiePool.java | 58 ++++ 14 files changed, 588 insertions(+), 554 deletions(-) delete mode 100644 dice/src/main/java/bjc/dicelang/neodice/DieFactory.java delete mode 100644 dice/src/main/java/bjc/dicelang/neodice/DiePoolFactory.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/die/RerollDie.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/DropFirstPool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/DropLastPool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/FilteredDiePool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/KeepFirstDiePool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/KeepLastDiePool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/SortedDiePool.java create mode 100644 dice/src/main/java/bjc/dicelang/neodice/diepool/TimesDiePool.java (limited to 'dice/src/main') diff --git a/dice/src/main/java/bjc/dicelang/neodice/Die.java b/dice/src/main/java/bjc/dicelang/neodice/Die.java index a986ca2..9bcbb0f 100644 --- a/dice/src/main/java/bjc/dicelang/neodice/Die.java +++ b/dice/src/main/java/bjc/dicelang/neodice/Die.java @@ -4,7 +4,8 @@ import java.util.*; import java.util.function.*; import java.util.stream.*; -import bjc.esodata.*; +import bjc.dicelang.neodice.die.*; +import bjc.dicelang.neodice.diepool.*; /** * Represents a single polyhedral die. @@ -67,105 +68,15 @@ public interface Die { default Iterator iterator(Random rng) { return IntStream.generate(() -> this.roll(rng)).iterator(); } -} -final class TimesDiePool implements DiePool { - private final Die contained; - private final int numDice; - - public TimesDiePool(Die contained, int numDice) { - this.contained = contained; - this.numDice = numDice; - } - - @Override - public int[] roll(Random rng) { - int[] results = new int[numDice]; - - for (int index = 0; index < numDice; index++) { - results[index] = contained.roll(rng); - } - - return results; - } - - @Override - public Die[] contained() { - Die[] results = new Die[numDice]; - - for (int index = 0; index < numDice; index++) { - results[index] = contained; - } - - return results; - } - - @Override - public String toString() { - return String.format("%d%s", numDice, contained); - } - - @Override - public int hashCode() { - return Objects.hash(contained, numDice); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - TimesDiePool other = (TimesDiePool) obj; - - return Objects.equals(contained, other.contained) && numDice == other.numDice; - } -} - -final class RerollDie implements Die { - private final Die contained; - - private final IntPredicate condition; - private final Function, Integer> chooser; - - private int limit = Integer.MAX_VALUE; - - - public RerollDie(Die contained, IntPredicate condition, - Function, Integer> chooser) { - this.contained = contained; - - this.condition = condition; - this.chooser = chooser; - } - - public RerollDie(Die contained, IntPredicate condition, - Function, Integer> chooser, int limit) { - this.contained = contained; - - this.condition = condition; - this.chooser = chooser; - - this.limit = limit; - } - - @Override - public int roll(Random rng) { - int roll = contained.roll(rng); - - MinMaxList newRolls = new MinMaxList( - Comparator.naturalOrder(), roll); - - int rerollCount = 0; - while (condition.test(roll) && rerollCount < limit) { - roll = contained.roll(rng); - newRolls.add(roll); - - rerollCount += 1; - } - - return chooser.apply(newRolls); + /** + * Create a simple polyhedral die with a fixed number of sides. + * + * @param sides The number of sides for the die. + * + * @return A die which returns a result from 1 to sides. + */ + static Die polyhedral(int sides) { + return new PolyhedralDie(sides); } - - // No toString, because IntPredicate can't be converted to a string } \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/DieFactory.java b/dice/src/main/java/bjc/dicelang/neodice/DieFactory.java deleted file mode 100644 index d9bae7e..0000000 --- a/dice/src/main/java/bjc/dicelang/neodice/DieFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -package bjc.dicelang.neodice; - -import java.util.*; - -/** - * Various static functions which create instances of Die. - * - * @author Ben Culkin - * - */ -public class DieFactory { - /** - * Create a simple polyhedral die with a fixed number of sides. - * - * @param sides The number of sides for the die. - * - * @return A die which returns a result from 1 to sides. - */ - public static Die polyhedral(int sides) { - return new PolyhedralDie(sides); - } -} - -final class PolyhedralDie implements Die { - private final int sides; - - public PolyhedralDie(int sides) { - this.sides = sides; - } - - @Override - public int roll(Random rng) { - // Dice are one-based, not zero-based. - return rng.nextInt(sides) + 1; - } - - @Override - public String toString() { - return String.format("d%d", sides); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + sides; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - PolyhedralDie other = (PolyhedralDie) obj; - - if (sides != other.sides) return false; - else return true; - } - - -} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/DiePool.java b/dice/src/main/java/bjc/dicelang/neodice/DiePool.java index 70dfa50..ac35988 100644 --- a/dice/src/main/java/bjc/dicelang/neodice/DiePool.java +++ b/dice/src/main/java/bjc/dicelang/neodice/DiePool.java @@ -3,6 +3,8 @@ package bjc.dicelang.neodice; import java.util.*; import java.util.function.*; +import bjc.dicelang.neodice.diepool.*; + /** * Represents a pool of dice. * @@ -183,315 +185,15 @@ public interface DiePool { default Iterator iterator(Random rng) { return Arrays.stream(this.roll(rng)).iterator(); } -} - -final class SortedDiePool implements DiePool { - private final boolean isDescending; - private final DiePool pool; - - public SortedDiePool(DiePool pool, boolean isDescending) { - this.pool = pool; - this.isDescending = isDescending; - } - - @Override - public int[] roll(Random rng) { - int[] rolls = pool.roll(rng); - - Arrays.sort(rolls); - - if (isDescending) { - int[] newRolls = new int[rolls.length]; - - int newIndex = newRolls.length; - for (int index = 0; index < rolls.length; index++) { - newRolls[newIndex--] = rolls[index]; - } - - return newRolls; - } else { - return rolls; - } - } - - @Override - public Die[] contained() { - return pool.contained(); - } - - @Override - public String toString() { - return String.format("%s (sorted %s)", pool, - isDescending ? " descending" : "ascending"); - } - - @Override - public int hashCode() { - return Objects.hash(isDescending, pool); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - SortedDiePool other = (SortedDiePool) obj; - - return isDescending == other.isDescending - && Objects.equals(pool, other.pool); - } -} - -final class FilteredDiePool implements DiePool { - private final DiePool pool; - private final IntPredicate filter; - - public FilteredDiePool(DiePool pool, IntPredicate filter) { - this.pool = pool; - this.filter = filter; - } - - @Override - public int[] roll(Random rng) { - int[] rolls = pool.roll(rng); - - return Arrays.stream(rolls).filter(filter).toArray(); - } - - @Override - public Die[] contained() { - return pool.contained(); - } - - // No toString, since there isn't any sensible to output the filter - - @Override - public int hashCode() { - return Objects.hash(filter, pool); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - FilteredDiePool other = (FilteredDiePool) obj; - - return Objects.equals(filter, other.filter) - && Objects.equals(pool, other.pool); - } -} - -final class DropFirstPool implements DiePool { - private final int number; - private final DiePool pool; - - public DropFirstPool(DiePool pool, int number) { - this.pool = pool; - this.number = number; - } - - @Override - public int[] roll(Random rng) { - int[] rolls = pool.roll(rng); - - if (number >= rolls.length) { - return new int[0]; - } else { - int[] newRolls = new int[rolls.length - number]; - - for (int index = number - 1; index < rolls.length; index++) { - newRolls[index - number] = rolls[index]; - } - - return newRolls; - } - } - - @Override - public Die[] contained() { - return pool.contained(); - } - - @Override - public String toString() { - return String.format("%sdF%d", pool, number); - } - - @Override - public int hashCode() { - return Objects.hash(number, pool); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - DropFirstPool other = (DropFirstPool) obj; - - return number == other.number && Objects.equals(pool, other.pool); - } -} -final class DropLastPool implements DiePool { - private final int number; - private final DiePool pool; - - public DropLastPool(DiePool pool, int number) { - this.pool = pool; - this.number = number; - } - - @Override - public int[] roll(Random rng) { - int[] rolls = pool.roll(rng); - - if (number >= rolls.length) { - return new int[0]; - } else { - int[] newRolls = new int[rolls.length - number]; - - for (int index = 0; index < rolls.length - number; index++) { - newRolls[index] = rolls[index]; - } - - return newRolls; - } - } - - @Override - public Die[] contained() { - return pool.contained(); - } - - @Override - public String toString() { - return String.format("%sdL%d", pool, number); - } - - @Override - public int hashCode() { - return Objects.hash(number, pool); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - DropLastPool other = (DropLastPool) obj; - - return number == other.number && Objects.equals(pool, other.pool); - } -} - -final class KeepFirstDiePool implements DiePool { - private final int number; - private final DiePool pool; - - public KeepFirstDiePool(DiePool pool, int number) { - this.pool = pool; - this.number = number; - } - - @Override - public int[] roll(Random rng) { - int[] rolls = pool.roll(rng); - - if (rolls.length >= number) { - return rolls; - } else { - int[] newRolls = new int[number]; - - for (int index = 0; index < number; index++) { - newRolls[index] = rolls[index]; - } - - return newRolls; - } - } - - @Override - public Die[] contained() { - return pool.contained(); - } - - @Override - public String toString() { - return String.format("%skF%d", pool, number); - } - - @Override - public int hashCode() { - return Objects.hash(number, pool); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - KeepFirstDiePool other = (KeepFirstDiePool) obj; - - return number == other.number && Objects.equals(pool, other.pool); - } -} - -final class KeepLastDiePool implements DiePool { - private final int number; - private final DiePool pool; - - public KeepLastDiePool(DiePool pool, int number) { - this.pool = pool; - this.number = number; - } - - @Override - public int[] roll(Random rng) { - int[] rolls = pool.roll(rng); - - if (rolls.length >= number) { - return rolls; - } else { - int[] newRolls = new int[number]; - - for (int index = number; index > index; index--) { - newRolls[index] = rolls[rolls.length - index]; - } - - return newRolls; - } - } - - @Override - public Die[] contained() { - return pool.contained(); - } - - @Override - public String toString() { - return String.format("%skL%d", pool, number); - } - - @Override - public int hashCode() { - return Objects.hash(number, pool); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - KeepLastDiePool other = (KeepLastDiePool) obj; - - return number == other.number && Objects.equals(pool, other.pool); + /** + * Create a die pool containing the provided dice. + * + * @param dice The dice to put into the pool. + * + * @return A pool which contains the provided dice. + */ + static DiePool containing(Die... dice) { + return new FixedDiePool(dice); } } \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/DiePoolFactory.java b/dice/src/main/java/bjc/dicelang/neodice/DiePoolFactory.java deleted file mode 100644 index 6d9314d..0000000 --- a/dice/src/main/java/bjc/dicelang/neodice/DiePoolFactory.java +++ /dev/null @@ -1,82 +0,0 @@ -package bjc.dicelang.neodice; - -import java.util.*; - -/** - * Various static functions which create instances of DiePool. - * - * @author Ben Culkin - * - */ -public class DiePoolFactory { - /** - * Create a die pool containing the provided dice. - * - * @param dice The dice to put into the pool. - * - * @return A pool which contains the provided dice. - */ - public static DiePool containing(Die... dice) { - return new FixedDiePool(dice); - } -} - -final class FixedDiePool implements DiePool { - private final Die[] dice; - - public FixedDiePool(Die[] dice) { - this.dice = dice; - } - - @Override - public int[] roll(Random rng) { - int[] results = new int[dice.length]; - - for (int index = 0; index < dice.length; index++) { - results[index] = dice[index].roll(rng); - } - - return results; - } - - @Override - public Die[] contained() { - return dice; - } - - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - - for (int i = 0; i < dice.length; i++) { - Die die = dice[i]; - - builder.append(die); - - // Don't add an extra trailing comma - if (i < dice.length - 1) builder.append(", "); - } - - return builder.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(dice); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - FixedDiePool other = (FixedDiePool) obj; - - return Arrays.equals(dice, other.dice); - } -} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java b/dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java new file mode 100644 index 0000000..c1bb2ac --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java @@ -0,0 +1,46 @@ +package bjc.dicelang.neodice.die; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class PolyhedralDie implements Die { + private final int sides; + + public PolyhedralDie(int sides) { + this.sides = sides; + } + + @Override + public int roll(Random rng) { + // Dice are one-based, not zero-based. + return rng.nextInt(sides) + 1; + } + + @Override + public String toString() { + return String.format("d%d", sides); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + sides; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + PolyhedralDie other = (PolyhedralDie) obj; + + if (sides != other.sides) return false; + else return true; + } + + +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/die/RerollDie.java b/dice/src/main/java/bjc/dicelang/neodice/die/RerollDie.java new file mode 100644 index 0000000..3cd369f --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/die/RerollDie.java @@ -0,0 +1,55 @@ +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 IntPredicate condition; + private final Function, Integer> chooser; + + private int limit = Integer.MAX_VALUE; + + + public RerollDie(Die contained, IntPredicate condition, + Function, Integer> chooser) { + this.contained = contained; + + this.condition = condition; + this.chooser = chooser; + } + + public RerollDie(Die contained, IntPredicate condition, + Function, Integer> chooser, int limit) { + this.contained = contained; + + this.condition = condition; + this.chooser = chooser; + + this.limit = limit; + } + + @Override + public int roll(Random rng) { + int roll = contained.roll(rng); + + MinMaxList newRolls = new MinMaxList( + Comparator.naturalOrder(), roll); + + int rerollCount = 0; + while (condition.test(roll) && rerollCount < limit) { + roll = contained.roll(rng); + newRolls.add(roll); + + rerollCount += 1; + } + + return chooser.apply(newRolls); + } + + // No toString, because IntPredicate can't be converted to a string +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/DropFirstPool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/DropFirstPool.java new file mode 100644 index 0000000..959678b --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/DropFirstPool.java @@ -0,0 +1,58 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class DropFirstPool implements DiePool { + private final int number; + private final DiePool pool; + + public DropFirstPool(DiePool pool, int number) { + this.pool = pool; + this.number = number; + } + + @Override + public int[] roll(Random rng) { + int[] rolls = pool.roll(rng); + + if (number >= rolls.length) { + return new int[0]; + } else { + int[] newRolls = new int[rolls.length - number]; + + for (int index = number - 1; index < rolls.length; index++) { + newRolls[index - number] = rolls[index]; + } + + return newRolls; + } + } + + @Override + public Die[] contained() { + return pool.contained(); + } + + @Override + public String toString() { + return String.format("%sdF%d", pool, number); + } + + @Override + public int hashCode() { + return Objects.hash(number, pool); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + DropFirstPool other = (DropFirstPool) obj; + + return number == other.number && Objects.equals(pool, other.pool); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/DropLastPool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/DropLastPool.java new file mode 100644 index 0000000..9503e8f --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/DropLastPool.java @@ -0,0 +1,58 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class DropLastPool implements DiePool { + private final int number; + private final DiePool pool; + + public DropLastPool(DiePool pool, int number) { + this.pool = pool; + this.number = number; + } + + @Override + public int[] roll(Random rng) { + int[] rolls = pool.roll(rng); + + if (number >= rolls.length) { + return new int[0]; + } else { + int[] newRolls = new int[rolls.length - number]; + + for (int index = 0; index < rolls.length - number; index++) { + newRolls[index] = rolls[index]; + } + + return newRolls; + } + } + + @Override + public Die[] contained() { + return pool.contained(); + } + + @Override + public String toString() { + return String.format("%sdL%d", pool, number); + } + + @Override + public int hashCode() { + return Objects.hash(number, pool); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + DropLastPool other = (DropLastPool) obj; + + return number == other.number && Objects.equals(pool, other.pool); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/FilteredDiePool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/FilteredDiePool.java new file mode 100644 index 0000000..34d274f --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/FilteredDiePool.java @@ -0,0 +1,47 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; +import java.util.function.*; + +import bjc.dicelang.neodice.*; + +public class FilteredDiePool implements DiePool { + private final DiePool pool; + private final IntPredicate filter; + + public FilteredDiePool(DiePool pool, IntPredicate filter) { + this.pool = pool; + this.filter = filter; + } + + @Override + public int[] roll(Random rng) { + int[] rolls = pool.roll(rng); + + return Arrays.stream(rolls).filter(filter).toArray(); + } + + @Override + public Die[] contained() { + return pool.contained(); + } + + // No toString, since there isn't any sensible to output the filter + + @Override + public int hashCode() { + return Objects.hash(filter, pool); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + FilteredDiePool other = (FilteredDiePool) obj; + + return Objects.equals(filter, other.filter) + && Objects.equals(pool, other.pool); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java new file mode 100644 index 0000000..c60b88a --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java @@ -0,0 +1,65 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class FixedDiePool implements DiePool { + private final Die[] dice; + + public FixedDiePool(Die[] dice) { + this.dice = dice; + } + + @Override + public int[] roll(Random rng) { + int[] results = new int[dice.length]; + + for (int index = 0; index < dice.length; index++) { + results[index] = dice[index].roll(rng); + } + + return results; + } + + @Override + public Die[] contained() { + return dice; + } + + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < dice.length; i++) { + Die die = dice[i]; + + builder.append(die); + + // Don't add an extra trailing comma + if (i < dice.length - 1) builder.append(", "); + } + + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(dice); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + FixedDiePool other = (FixedDiePool) obj; + + return Arrays.equals(dice, other.dice); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/KeepFirstDiePool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/KeepFirstDiePool.java new file mode 100644 index 0000000..d31f104 --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/KeepFirstDiePool.java @@ -0,0 +1,58 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class KeepFirstDiePool implements DiePool { + private final int number; + private final DiePool pool; + + public KeepFirstDiePool(DiePool pool, int number) { + this.pool = pool; + this.number = number; + } + + @Override + public int[] roll(Random rng) { + int[] rolls = pool.roll(rng); + + if (rolls.length >= number) { + return rolls; + } else { + int[] newRolls = new int[number]; + + for (int index = 0; index < number; index++) { + newRolls[index] = rolls[index]; + } + + return newRolls; + } + } + + @Override + public Die[] contained() { + return pool.contained(); + } + + @Override + public String toString() { + return String.format("%skF%d", pool, number); + } + + @Override + public int hashCode() { + return Objects.hash(number, pool); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + KeepFirstDiePool other = (KeepFirstDiePool) obj; + + return number == other.number && Objects.equals(pool, other.pool); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/KeepLastDiePool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/KeepLastDiePool.java new file mode 100644 index 0000000..1e2d1ae --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/KeepLastDiePool.java @@ -0,0 +1,58 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class KeepLastDiePool implements DiePool { + private final int number; + private final DiePool pool; + + public KeepLastDiePool(DiePool pool, int number) { + this.pool = pool; + this.number = number; + } + + @Override + public int[] roll(Random rng) { + int[] rolls = pool.roll(rng); + + if (rolls.length >= number) { + return rolls; + } else { + int[] newRolls = new int[number]; + + for (int index = number; index > index; index--) { + newRolls[index] = rolls[rolls.length - index]; + } + + return newRolls; + } + } + + @Override + public Die[] contained() { + return pool.contained(); + } + + @Override + public String toString() { + return String.format("%skL%d", pool, number); + } + + @Override + public int hashCode() { + return Objects.hash(number, pool); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + KeepLastDiePool other = (KeepLastDiePool) obj; + + return number == other.number && Objects.equals(pool, other.pool); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/SortedDiePool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/SortedDiePool.java new file mode 100644 index 0000000..79599c1 --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/SortedDiePool.java @@ -0,0 +1,63 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class SortedDiePool implements DiePool { + private final boolean isDescending; + private final DiePool pool; + + public SortedDiePool(DiePool pool, boolean isDescending) { + this.pool = pool; + this.isDescending = isDescending; + } + + @Override + public int[] roll(Random rng) { + int[] rolls = pool.roll(rng); + + Arrays.sort(rolls); + + if (isDescending) { + int[] newRolls = new int[rolls.length]; + + int newIndex = newRolls.length; + for (int index = 0; index < rolls.length; index++) { + newRolls[newIndex--] = rolls[index]; + } + + return newRolls; + } else { + return rolls; + } + } + + @Override + public Die[] contained() { + return pool.contained(); + } + + @Override + public String toString() { + return String.format("%s (sorted %s)", pool, + isDescending ? " descending" : "ascending"); + } + + @Override + public int hashCode() { + return Objects.hash(isDescending, pool); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + SortedDiePool other = (SortedDiePool) obj; + + return isDescending == other.isDescending + && Objects.equals(pool, other.pool); + } +} \ No newline at end of file diff --git a/dice/src/main/java/bjc/dicelang/neodice/diepool/TimesDiePool.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/TimesDiePool.java new file mode 100644 index 0000000..1b34247 --- /dev/null +++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/TimesDiePool.java @@ -0,0 +1,58 @@ +package bjc.dicelang.neodice.diepool; + +import java.util.*; + +import bjc.dicelang.neodice.*; + +public class TimesDiePool implements DiePool { + private final Die contained; + private final int numDice; + + public TimesDiePool(Die contained, int numDice) { + this.contained = contained; + this.numDice = numDice; + } + + @Override + public int[] roll(Random rng) { + int[] results = new int[numDice]; + + for (int index = 0; index < numDice; index++) { + results[index] = contained.roll(rng); + } + + return results; + } + + @Override + public Die[] contained() { + Die[] results = new Die[numDice]; + + for (int index = 0; index < numDice; index++) { + results[index] = contained; + } + + return results; + } + + @Override + public String toString() { + return String.format("%d%s", numDice, contained); + } + + @Override + public int hashCode() { + return Objects.hash(contained, numDice); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + TimesDiePool other = (TimesDiePool) obj; + + return Objects.equals(contained, other.contained) && numDice == other.numDice; + } +} \ No newline at end of file -- cgit v1.2.3