summaryrefslogtreecommitdiff
path: root/dice
diff options
context:
space:
mode:
Diffstat (limited to 'dice')
-rw-r--r--dice/src/example/java/bjc/dicelang/neodice/commands/PolyhedralDieCommand.java2
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/Die.java111
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/DiePool.java320
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java (renamed from dice/src/main/java/bjc/dicelang/neodice/DieFactory.java)23
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/die/RerollDie.java55
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/DropFirstPool.java58
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/DropLastPool.java58
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/FilteredDiePool.java47
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java (renamed from dice/src/main/java/bjc/dicelang/neodice/DiePoolFactory.java)23
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/KeepFirstDiePool.java58
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/KeepLastDiePool.java58
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/SortedDiePool.java63
-rw-r--r--dice/src/main/java/bjc/dicelang/neodice/diepool/TimesDiePool.java58
-rw-r--r--dice/src/test/java/bjc/dicelang/neodice/DiePoolTest.java8
-rw-r--r--dice/src/test/java/bjc/dicelang/neodice/DieTest.java10
15 files changed, 493 insertions, 459 deletions
diff --git a/dice/src/example/java/bjc/dicelang/neodice/commands/PolyhedralDieCommand.java b/dice/src/example/java/bjc/dicelang/neodice/commands/PolyhedralDieCommand.java
index 02fc9cf..95e9dff 100644
--- a/dice/src/example/java/bjc/dicelang/neodice/commands/PolyhedralDieCommand.java
+++ b/dice/src/example/java/bjc/dicelang/neodice/commands/PolyhedralDieCommand.java
@@ -20,7 +20,7 @@ public class PolyhedralDieCommand implements Command {
if (numSides < 0) throw new DieBoxException("Number of sides to polyhedral-die was not valid (must be less than 0, was %d)", numSides);
- return new DieStatementValue(DieFactory.polyhedral(numSides));
+ return new DieStatementValue(Die.polyhedral(numSides));
} else {
throw new DieBoxException("Number of sides to polyhedral-die wasn't an integer (was %s, of type %s)",
sideValue, sideValue.type);
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<Integer> 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<MinMaxList<Integer>, Integer> chooser;
-
- private int limit = Integer.MAX_VALUE;
-
-
- public RerollDie(Die contained, IntPredicate condition,
- Function<MinMaxList<Integer>, Integer> chooser) {
- this.contained = contained;
-
- this.condition = condition;
- this.chooser = chooser;
- }
-
- public RerollDie(Die contained, IntPredicate condition,
- Function<MinMaxList<Integer>, 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<Integer> newRolls = new MinMaxList<Integer>(
- 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/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<Integer> 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/DieFactory.java b/dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java
index d9bae7e..c1bb2ac 100644
--- a/dice/src/main/java/bjc/dicelang/neodice/DieFactory.java
+++ b/dice/src/main/java/bjc/dicelang/neodice/die/PolyhedralDie.java
@@ -1,27 +1,10 @@
-package bjc.dicelang.neodice;
+package bjc.dicelang.neodice.die;
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);
- }
-}
+import bjc.dicelang.neodice.*;
-final class PolyhedralDie implements Die {
+public class PolyhedralDie implements Die {
private final int sides;
public PolyhedralDie(int sides) {
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<MinMaxList<Integer>, Integer> chooser;
+
+ private int limit = Integer.MAX_VALUE;
+
+
+ public RerollDie(Die contained, IntPredicate condition,
+ Function<MinMaxList<Integer>, Integer> chooser) {
+ this.contained = contained;
+
+ this.condition = condition;
+ this.chooser = chooser;
+ }
+
+ public RerollDie(Die contained, IntPredicate condition,
+ Function<MinMaxList<Integer>, 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<Integer> newRolls = new MinMaxList<Integer>(
+ 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/DiePoolFactory.java b/dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java
index 6d9314d..c60b88a 100644
--- a/dice/src/main/java/bjc/dicelang/neodice/DiePoolFactory.java
+++ b/dice/src/main/java/bjc/dicelang/neodice/diepool/FixedDiePool.java
@@ -1,27 +1,10 @@
-package bjc.dicelang.neodice;
+package bjc.dicelang.neodice.diepool;
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);
- }
-}
+import bjc.dicelang.neodice.*;
-final class FixedDiePool implements DiePool {
+public class FixedDiePool implements DiePool {
private final Die[] dice;
public FixedDiePool(Die[] dice) {
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
diff --git a/dice/src/test/java/bjc/dicelang/neodice/DiePoolTest.java b/dice/src/test/java/bjc/dicelang/neodice/DiePoolTest.java
index 1a217d3..3614cd3 100644
--- a/dice/src/test/java/bjc/dicelang/neodice/DiePoolTest.java
+++ b/dice/src/test/java/bjc/dicelang/neodice/DiePoolTest.java
@@ -12,8 +12,8 @@ public class DiePoolTest {
@Test
public void containedOneDieYieldsOneDie() {
- Die oneSidedDie = DieFactory.polyhedral(1);
- DiePool pool = DiePoolFactory.containing(oneSidedDie);
+ Die oneSidedDie = Die.polyhedral(1);
+ DiePool pool = DiePool.containing(oneSidedDie);
assertArrayEquals(
"A contained pool created with one die, yields that die",
@@ -22,8 +22,8 @@ public class DiePoolTest {
@Test
public void containedOneDieRollsOneDie() {
- Die oneSidedDie = DieFactory.polyhedral(1);
- DiePool pool = DiePoolFactory.containing(oneSidedDie);
+ Die oneSidedDie = Die.polyhedral(1);
+ DiePool pool = DiePool.containing(oneSidedDie);
for (int i = 0; i < 10; i++) {
assertArrayEquals("One-die pools roll one die",
diff --git a/dice/src/test/java/bjc/dicelang/neodice/DieTest.java b/dice/src/test/java/bjc/dicelang/neodice/DieTest.java
index 60f2ae2..202688b 100644
--- a/dice/src/test/java/bjc/dicelang/neodice/DieTest.java
+++ b/dice/src/test/java/bjc/dicelang/neodice/DieTest.java
@@ -12,7 +12,7 @@ public class DieTest {
@Test
public void onesidedDiceReturnOne() {
- Die die = DieFactory.polyhedral(1);
+ Die die = Die.polyhedral(1);
for (int i = 0; i < 10; i++) {
assertEquals("One-sided dice always return 1", 1, die.roll(rng));
@@ -21,7 +21,7 @@ public class DieTest {
@Test
public void polyhedralDiceStayInRange() {
- Die die = DieFactory.polyhedral(6);
+ Die die = Die.polyhedral(6);
for (int i = 0; i < 50; i++) {
int result = die.roll(rng);
@@ -34,9 +34,9 @@ public class DieTest {
@Test
public void polyhedralDiceEqualityFunctionsProperly() {
- Die dieA1 = DieFactory.polyhedral(1);
- Die dieA2 = DieFactory.polyhedral(1);
- Die dieB1 = DieFactory.polyhedral(2);
+ Die dieA1 = Die.polyhedral(1);
+ Die dieA2 = Die.polyhedral(1);
+ Die dieB1 = Die.polyhedral(2);
assertEquals("Polyhedral dice with the same number of sides are equal",
dieA1, dieA2);