diff options
| author | student <student@localhost> | 2018-02-12 13:44:33 -0500 |
|---|---|---|
| committer | student <student@localhost> | 2018-02-12 13:44:33 -0500 |
| commit | e0bae41482973b4a3d4a8607cd6cb308cf6fc50c (patch) | |
| tree | 329216ba23462489e5c047f896d5c634f55a19af /dice/src | |
| parent | 75b790db6a759b3057c294bae3f669e5b01c8688 (diff) | |
Refactor DieExpression
DieExpression was split into two classes to make things easier to deal
with.
Diffstat (limited to 'dice/src')
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()); + } +} |
