summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstudent <student@localhost>2018-02-12 13:44:33 -0500
committerstudent <student@localhost>2018-02-12 13:44:33 -0500
commite0bae41482973b4a3d4a8607cd6cb308cf6fc50c (patch)
tree329216ba23462489e5c047f896d5c634f55a19af
parent75b790db6a759b3057c294bae3f669e5b01c8688 (diff)
Refactor DieExpression
DieExpression was split into two classes to make things easier to deal with.
-rw-r--r--dice/src/main/java/bjc/dicelang/dice/DiceBox.java181
-rw-r--r--dice/src/main/java/bjc/dicelang/dice/DiceExpression.java17
-rw-r--r--dice/src/main/java/bjc/dicelang/dice/DieExpression.java69
-rw-r--r--dice/src/main/java/bjc/dicelang/dice/ListDiceExpression.java59
-rw-r--r--dice/src/main/java/bjc/dicelang/dice/ScalarDiceExpression.java52
5 files changed, 216 insertions, 162 deletions
diff --git a/dice/src/main/java/bjc/dicelang/dice/DiceBox.java b/dice/src/main/java/bjc/dicelang/dice/DiceBox.java
index c14fe49..f3b01a8 100644
--- a/dice/src/main/java/bjc/dicelang/dice/DiceBox.java
+++ b/dice/src/main/java/bjc/dicelang/dice/DiceBox.java
@@ -16,18 +16,17 @@ public class DiceBox {
* Parse a die expression from a string.
*
* @param expString
- * The string to parse.
+ * The string to parse.
*
* @return The die expression from the string, or null if it wasn't one
*/
- public static DieExpression parseExpression(final String expString) {
+ public static DiceExpression parseExpression(final String expString) {
try {
return doParseExpression(expString);
} catch (Exception ex) {
/*
- * @TODO 10/08/17 Ben Culkin :DieErrors :ErrorRefactor
- * Use different types of exceptions to provide
- * better error messages.
+ * @TODO 10/08/17 Ben Culkin :DieErrors :ErrorRefactor Use different types of
+ * exceptions to provide better error messages.
*/
String exMessage = ex.getMessage();
@@ -38,7 +37,7 @@ public class DiceBox {
}
}
- private static DieExpression doParseExpression(final String expString) {
+ private static DiceExpression doParseExpression(final String expString) {
/* Only bother with valid expressions. */
if (!isValidExpression(expString)) {
return null;
@@ -46,12 +45,11 @@ public class DiceBox {
if (scalarDiePattern.matcher(expString).matches()) {
/* Parse scalar die. */
- /* @TODO 10/08/17 Ben Culkin :SubstringIndexOf
- * This substring/index of call should be
- * abstracted into its own method so as to make the
- * code more explanatory and ensure that things
- * like the return code of indexOf are correctly
- * checked.
+ /*
+ * @TODO 10/08/17 Ben Culkin :SubstringIndexOf This substring/index of call
+ * should be abstracted into its own method so as to make the code more
+ * explanatory and ensure that things like the return code of indexOf are
+ * correctly checked.
*/
final String dieString = expString.substring(0, expString.indexOf('s'));
@@ -59,7 +57,7 @@ public class DiceBox {
final Die scal = new ScalarDie(lar);
- return new DieExpression(scal);
+ return new ScalarDiceExpression(scal);
} else if (simpleDiePattern.matcher(expString).matches()) {
/* Parse simple die groups. */
final String[] dieParts = expString.split("d");
@@ -76,79 +74,94 @@ public class DiceBox {
final Die scal = new SimpleDie(left, right);
- return new DieExpression(scal);
+ return new ScalarDiceExpression(scal);
} else if (fudgeDiePattern.matcher(expString).matches()) {
/* Parse fudge dice. */
/* :SubstringIndexOf */
final String nDice = expString.substring(0, expString.indexOf('d'));
- final Die fudge = new FudgeDie(Long.parseLong(nDice));
+ final Die fudge = new FudgeDie(Long.parseLong(nDice));
- return new DieExpression(fudge);
+ return new ScalarDiceExpression(fudge);
} else if (compoundDiePattern.matcher(expString).matches()) {
/* Parse compound die expressions. */
final String[] dieParts = expString.split("c");
- /* @TODO 10/08/17 :SplitParse
- * Should this split string/parse split parts be
- * abstracted into something else that handles
- * doing the splitting correctly, as well as
- * making sure that the resulting DieExpressions
- * are of the right type?
+ /*
+ * @TODO 10/08/17 :SplitParse
+ *
+ * Should this split string/parse split parts be abstracted into something else
+ * that handles doing the splitting correctly, as well as making sure that the
+ * resulting DieExpressions are of the right type?
*/
- final DieExpression left = parseExpression(dieParts[0]);
- final DieExpression right = parseExpression(dieParts[1]);
+ final DiceExpression left = parseExpression(dieParts[0]);
+ final DiceExpression right = parseExpression(dieParts[1]);
/* :ErrorRefactor */
- if (left.isList) {
- System.out.printf("ERROR: Expected a scalar die expression for lhs of compound die, got a list expression instead (%s)\n",
- left);
- } else if (right.isList) {
- System.out.printf("ERROR: Expected a scalar die expression for rhs of compound die, got a list expression instead (%s)\n",
- right);
+ if (left.isList()) {
+ System.out.printf(
+ "ERROR: Expected a scalar dice expression for lhs of compound die, got a list expression instead (%s)\n",
+ left);
+ } else if (right.isList()) {
+ System.out.printf(
+ "ERROR: Expected a scalar dice expression for rhs of compound die, got a list expression instead (%s)\n",
+ right);
}
- final Die compound = new CompoundDie(left.scalar, right.scalar);
+ Die lhs = ((ScalarDiceExpression) left).scalar;
+ Die rhs = ((ScalarDiceExpression) right).scalar;
- return new DieExpression(compound);
+ final Die compound = new CompoundDie(lhs, rhs);
+
+ return new ScalarDiceExpression(compound);
} else if (compoundingDiePattern.matcher(expString).matches()) {
/* Parse compounding die expressions. */
final String[] dieParts = expString.split("!!");
- final DieExpression left = parseExpression(dieParts[0]);
+ final DiceExpression left = parseExpression(dieParts[0]);
final Predicate<Long> right = deriveCond(dieParts[1]);
- final Die scal = new CompoundingDie(left.scalar, right, dieParts[1]);
+ Die die = ((ScalarDiceExpression) left).scalar;
+
+ final Die scal = new CompoundingDie(die, right, dieParts[1]);
- return new DieExpression(scal);
+ return new ScalarDiceExpression(scal);
} else if (explodingDiePattern.matcher(expString).matches()) {
/* Parse exploding die expressions. */
final String[] dieParts = expString.split("!");
- final DieExpression left = parseExpression(dieParts[0]);
+ final DiceExpression left = parseExpression(dieParts[0]);
final Predicate<Long> right = deriveCond(dieParts[1]);
- final DieList lst = new ExplodingDice(left.scalar, right, dieParts[1], false);
+ Die lhs = ((ScalarDiceExpression) left).scalar;
- return new DieExpression(lst);
+ final DieList lst = new ExplodingDice(lhs, right, dieParts[1], false);
+
+ return new ListDiceExpression(lst);
} else if (penetratingDiePattern.matcher(expString).matches()) {
/* Parse penetrating die expressions. */
final String[] dieParts = expString.split("p!");
- final DieExpression left = parseExpression(dieParts[0]);
+ final DiceExpression left = parseExpression(dieParts[0]);
final Predicate<Long> right = deriveCond(dieParts[1]);
- final DieList lst = new ExplodingDice(left.scalar, right, dieParts[1], true);
+ Die lhs = ((ScalarDiceExpression) left).scalar;
+
+ final DieList lst = new ExplodingDice(lhs, right, dieParts[1], true);
- return new DieExpression(lst);
+ return new ListDiceExpression(lst);
} else if (diceListPattern.matcher(expString).matches()) {
/* Parse simple die lists. */
final String[] dieParts = expString.split("dl");
- final DieExpression left = parseExpression(dieParts[0]);
- final DieExpression right = parseExpression(dieParts[1]);
+ final DiceExpression left = parseExpression(dieParts[0]);
+ final DiceExpression right = parseExpression(dieParts[1]);
- final DieList lst = new SimpleDieList(left.scalar, right.scalar);
- return new DieExpression(lst);
+ Die lhs = ((ScalarDiceExpression) left).scalar;
+ Die rhs = ((ScalarDiceExpression) right).scalar;
+
+ final DieList lst = new SimpleDieList(lhs, rhs);
+
+ return new ListDiceExpression(lst);
}
/* Unhandled type of die expression. */
@@ -157,10 +170,10 @@ public class DiceBox {
}
/* The strings and patterns used for matching. */
- /* @TODO 10/08/17 Ben Culkin :RegexResource
- * These regexes and patterns should be moved to something
- * external, probably using the SimpleProperties-based system that
- * BJC-Utils2 uses.
+ /*
+ * @TODO 10/08/17 Ben Culkin :RegexResource These regexes and patterns should be
+ * moved to something external, probably using the SimpleProperties-based system
+ * that BJC-Utils2 uses.
*/
/* Defines a comparison predicate. */
private static final String comparePoint = "[<>=]\\d+";
@@ -170,58 +183,48 @@ public class DiceBox {
*
* This is just a number.
*/
- private static final String scalarDie = "[\\+\\-]?\\d+sd";
- private static final Pattern scalarDiePattern = Pattern.compile(
- String.format("\\A%s\\Z", scalarDie));
+ private static final String scalarDie = "[\\+\\-]?\\d+sd";
+ private static final Pattern scalarDiePattern = Pattern.compile(String.format("\\A%s\\Z", scalarDie));
/*
* Defines a simple die.
*
* This is a group of one or more dice of the same size.
*/
- private static final String simpleDie = "(?:\\d+)?d\\d+";
- private static final Pattern simpleDiePattern = Pattern.compile("\\A" +
- simpleDie + "\\Z");
+ private static final String simpleDie = "(?:\\d+)?d\\d+";
+ private static final Pattern simpleDiePattern = Pattern.compile("\\A" + simpleDie + "\\Z");
/*
* Defines a fudge die.
*
- * This is like a simple die, but all the die give -1, 0, or 1 as
- * results.
+ * This is like a simple die, but all the die give -1, 0, or 1 as results.
*/
- private static final String fudgeDie = "(?:\\d+)?dF";
- private static final Pattern fudgeDiePattern = Pattern.compile("\\A" + fudgeDie +
- "\\Z");
+ private static final String fudgeDie = "(?:\\d+)?dF";
+ private static final Pattern fudgeDiePattern = Pattern.compile("\\A" + fudgeDie + "\\Z");
/*
* Defines a compound die.
*
* This is like using two d10's to simulate a d100
*/
- private static final String compoundDie = simpleDie + "c(?:(?:" +
- simpleDie + ")|(?:\\d+))";
- private static final Pattern compoundDiePattern = Pattern.compile("\\A" +
- compoundDie + "\\Z");
+ private static final String compoundDie = simpleDie + "c(?:(?:" + simpleDie + ")|(?:\\d+))";
+ private static final Pattern compoundDiePattern = Pattern.compile("\\A" + compoundDie + "\\Z");
/*
* Defines a compound group.
*
* This is used for forming die list type expressions.
*/
- private static final String compoundGroup = "(?:(?:" + scalarDie + ")|(?:" + simpleDie +
- ")|(?:" + compoundDie
- + ")|(?:" + fudgeDie + "))";
+ private static final String compoundGroup = "(?:(?:" + scalarDie + ")|(?:" + simpleDie + ")|(?:" + compoundDie
+ + ")|(?:" + fudgeDie + "))";
/*
* Defines a compounding die.
*
- * This is like an exploding die, but is a single die, not a group of
- * them.
+ * This is like an exploding die, but is a single die, not a group of them.
*/
- private static final String compoundingDie = compoundGroup + "!!" +
- comparePoint;
- private static final Pattern compoundingDiePattern = Pattern.compile("\\A" +
- compoundingDie + "\\Z");
+ private static final String compoundingDie = compoundGroup + "!!" + comparePoint;
+ private static final Pattern compoundingDiePattern = Pattern.compile("\\A" + compoundingDie + "\\Z");
/*
* Defines an exploding die.
@@ -229,43 +232,36 @@ public class DiceBox {
* This is a die that you reroll the component of if it meets a certain
* condition.
*/
- private static final String explodingDie = compoundGroup + "!" +
- comparePoint;
- private static final Pattern explodingDiePattern = Pattern.compile("\\A" +
- explodingDie + "\\Z");
+ private static final String explodingDie = compoundGroup + "!" + comparePoint;
+ private static final Pattern explodingDiePattern = Pattern.compile("\\A" + explodingDie + "\\Z");
/*
* Defines a penetrating die.
*
- * This is like an exploding die, but the exploded result gets a -1
- * penalty.
+ * This is like an exploding die, but the exploded result gets a -1 penalty.
*/
- private static final String penetratingDie = compoundGroup + "!" +
- comparePoint;
- private static final Pattern penetratingDiePattern = Pattern.compile("\\A" +
- penetratingDie + "\\Z");
+ private static final String penetratingDie = compoundGroup + "!" + comparePoint;
+ private static final Pattern penetratingDiePattern = Pattern.compile("\\A" + penetratingDie + "\\Z");
/*
* Defines a die list.
*
* This is an array of dice of the specified size.
*/
- private static final String diceList = compoundGroup + "dl" + compoundGroup;
- private static final Pattern diceListPattern = Pattern.compile("\\A" + diceList +
- "\\Z");
+ private static final String diceList = compoundGroup + "dl" + compoundGroup;
+ private static final Pattern diceListPattern = Pattern.compile("\\A" + diceList + "\\Z");
/**
* Check if a given string is a valid die expression.
*
* @param exp
- * The string to check validity of.
+ * The string to check validity of.
*
* @return Whether or not the string is a valid command.
*/
public static boolean isValidExpression(final String exp) {
- /* @NOTE
- * Should this matcher/matches expression be abstracted in
- * some way?
+ /*
+ * @NOTE Should this matcher/matches expression be abstracted in some way?
*/
if (scalarDiePattern.matcher(exp).matches()) {
return true;
@@ -292,9 +288,8 @@ public class DiceBox {
private static Predicate<Long> deriveCond(final String patt) {
final long num = Long.parseLong(patt.substring(1));
- /* @NOTE
- * Should this be extended in some way, to provide other
- * operators?
+ /*
+ * @NOTE Should this be extended in some way, to provide other operators?
*/
switch (patt.charAt(0)) {
case '<':
diff --git a/dice/src/main/java/bjc/dicelang/dice/DiceExpression.java b/dice/src/main/java/bjc/dicelang/dice/DiceExpression.java
new file mode 100644
index 0000000..41b2147
--- /dev/null
+++ b/dice/src/main/java/bjc/dicelang/dice/DiceExpression.java
@@ -0,0 +1,17 @@
+package bjc.dicelang.dice;
+
+/**
+ * Represents either a die or a die list.
+ *
+ * @author Ben Culkin
+ */
+public interface DiceExpression {
+ /**
+ * Get the value of this expression as a string.
+ *
+ * @return The value of the expression as a string.
+ */
+ public String value();
+
+ public boolean isList();
+}
diff --git a/dice/src/main/java/bjc/dicelang/dice/DieExpression.java b/dice/src/main/java/bjc/dicelang/dice/DieExpression.java
deleted file mode 100644
index b8faeda..0000000
--- a/dice/src/main/java/bjc/dicelang/dice/DieExpression.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package bjc.dicelang.dice;
-
-import java.util.Arrays;
-
-/*
- * @NOTE
- * I'm not a particularly large fan of sticking everything on this class
- * and just documenting which fields are tied together in a non-obvious
- * way. I think a class hierarchy might be better, but I am unsure of the
- * details.
- */
-/**
- * Represents either a die or a die list.
- *
- * @author Ben Culkin
- */
-public class DieExpression {
- /** Is this expression a list? */
- public final boolean isList;
-
- /** The scalar value in this expression, if there is one. */
- public Die scalar;
- /** The list value in this expression, if there is one. */
- public DieList list;
-
- /**
- * Create a scalar die expression.
- *
- * @param scal
- * The scalar value of this expression.
- */
- public DieExpression(final Die scal) {
- isList = false;
- scalar = scal;
- }
-
- /**
- * Create a list die expression.
- *
- * @param lst
- * The list value of this expression.
- */
- public DieExpression(final DieList lst) {
- isList = true;
- list = lst;
- }
-
- @Override
- public String toString() {
- if (isList) {
- return list.toString();
- }
-
- return scalar.toString();
- }
-
- /**
- * Get the value of this expression as a string.
- *
- * @return The value of the expression as a string.
- */
- public String value() {
- if (isList) {
- return Arrays.toString(list.roll());
- }
-
- return Long.toString(scalar.roll());
- }
-}
diff --git a/dice/src/main/java/bjc/dicelang/dice/ListDiceExpression.java b/dice/src/main/java/bjc/dicelang/dice/ListDiceExpression.java
new file mode 100644
index 0000000..e47291b
--- /dev/null
+++ b/dice/src/main/java/bjc/dicelang/dice/ListDiceExpression.java
@@ -0,0 +1,59 @@
+package bjc.dicelang.dice;
+
+import java.util.Arrays;
+
+public class ListDiceExpression implements DiceExpression {
+
+ /** The list value in this expression, if there is one. */
+ public DieList list;
+
+ /**
+ * Create a list die expression.
+ *
+ * @param lst
+ * The list value of this expression.
+ */
+ public ListDiceExpression(final DieList lst) {
+ list = lst;
+ }
+
+ @Override
+ public String value() {
+ return Arrays.toString(list.roll());
+ }
+
+ @Override
+ public boolean isList() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return list.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((list == null) ? 0 : list.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ListDiceExpression other = (ListDiceExpression) obj;
+ if (list == null) {
+ if (other.list != null)
+ return false;
+ } else if (!list.equals(other.list))
+ return false;
+ return true;
+ }
+}
diff --git a/dice/src/main/java/bjc/dicelang/dice/ScalarDiceExpression.java b/dice/src/main/java/bjc/dicelang/dice/ScalarDiceExpression.java
new file mode 100644
index 0000000..6951f49
--- /dev/null
+++ b/dice/src/main/java/bjc/dicelang/dice/ScalarDiceExpression.java
@@ -0,0 +1,52 @@
+package bjc.dicelang.dice;
+
+public class ScalarDiceExpression implements DiceExpression {
+ /**
+ * The scalar value in this expression, if there is one.
+ */
+ public Die scalar;
+
+ public ScalarDiceExpression(Die scal) {
+ scalar = scal;
+ }
+
+ @Override
+ public boolean isList() {
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((scalar == null) ? 0 : scalar.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ScalarDiceExpression other = (ScalarDiceExpression) obj;
+ if (scalar == null) {
+ if (other.scalar != null)
+ return false;
+ } else if (!scalar.equals(other.scalar))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return scalar.toString();
+ }
+
+ @Override
+ public String value() {
+ return Long.toString(scalar.roll());
+ }
+}