From 1bff7e49ed64d74e36d901e84c594cf63b58350b Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Fri, 18 Mar 2016 19:47:49 -0400 Subject: General changes to the dice package The biggest change is the addition of variables and assignment --- .../java/bjc/utils/dice/BindingDiceExpression.java | 43 ++++++++ .../src/main/java/bjc/utils/dice/ComplexDice.java | 103 +++++++++++++++++++ .../src/main/java/bjc/utils/dice/CompoundDice.java | 4 + .../bjc/utils/dice/CompoundDiceExpression.java | 16 ++- .../java/bjc/utils/dice/DiceExpressionBuilder.java | 4 +- .../java/bjc/utils/dice/DiceExpressionParser.java | 112 +++++++++++++-------- .../java/bjc/utils/dice/DiceExpressionType.java | 19 +++- BJC-Utils2/src/main/java/bjc/utils/dice/Die.java | 21 ++-- .../src/main/java/bjc/utils/dice/LazyDice.java | 93 ----------------- .../main/java/bjc/utils/dice/PolyhedralDice.java | 28 +++--- .../bjc/utils/dice/ReferenceDiceExpression.java | 60 +++++++++++ .../java/bjc/utils/dice/ScalarDiceExpression.java | 16 ++- .../src/main/java/bjc/utils/dice/ScalarDie.java | 10 +- 13 files changed, 364 insertions(+), 165 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/dice/BindingDiceExpression.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/dice/ComplexDice.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/dice/LazyDice.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/dice/ReferenceDiceExpression.java (limited to 'BJC-Utils2/src/main/java/bjc') diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/BindingDiceExpression.java b/BJC-Utils2/src/main/java/bjc/utils/dice/BindingDiceExpression.java new file mode 100644 index 0000000..51e159d --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/BindingDiceExpression.java @@ -0,0 +1,43 @@ +package bjc.utils.dice; + +import java.util.Map; + +/** + * A variable expression that represents binding a variable to a name in an + * enviroment + * + * @author ben + * + */ +public class BindingDiceExpression implements IDiceExpression { + private String name; + private IDiceExpression exp; + + /** + * Create a new dice expression binder + * + * @param name + * The name of the variable to bind + * @param exp + * The expression to bind to the variable + * @param env + * The enviroment to bind it in + */ + public BindingDiceExpression(String name, IDiceExpression exp, + Map env) { + this.name = name; + this.exp = exp; + + env.put(name, exp); + } + + @Override + public int roll() { + return exp.roll(); + } + + @Override + public String toString() { + return "assign[n=" + name + ", exp=" + exp.toString() + "]"; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ComplexDice.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ComplexDice.java new file mode 100644 index 0000000..98a510a --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ComplexDice.java @@ -0,0 +1,103 @@ +package bjc.utils.dice; + +/** + * Implements a collection of one or more of a particular die, where the + * number of dice in the group is variable. + * + * @author ben + * + */ +public class ComplexDice implements IDiceExpression { + /** + * The die being rolled + */ + private IDiceExpression die; + + /** + * The number of the specified die to roll + */ + private IDiceExpression nDice; + + /** + * Create a new collection of dice + * + * @param nDce + * The number of dice in the collection + * @param de + * The type of dice the collection is composed of + */ + public ComplexDice(IDiceExpression nDce, IDiceExpression de) { + nDice = nDce; + die = de; + } + + /** + * Create a new collection of dice + * + * @param nDce + * The number of dice in the collection + * @param de + * The type of dice the collection is composed of + */ + public ComplexDice(int nSides, int de) { + nDice = new ScalarDie(nSides); + die = new Die(de); + } + + @Override + public int roll() { + int res = 0; + + /* + * Add the results of rolling each die + */ + int nRoll = nDice.roll(); + + for (int i = 0; i < nRoll; i++) { + res += die.roll(); + } + + return res; + } + + /** + * Create a dice from a string expression + * + * @param dice + * The string to parse the dice from + * @return A dice group parsed from the string + */ + public static ComplexDice fromString(String dice) { + /* + * Split it on the dice type marker + */ + String[] strangs = dice.split("d"); + + try { + /* + * Create the actual dice + */ + return new ComplexDice( + new ScalarDie(Integer.parseInt(strangs[0])), + new Die(Integer.parseInt(strangs[1]))); + } catch (NumberFormatException nfex) { + /* + * Tell the user the expression is invalid + */ + throw new IllegalArgumentException( + "Attempted to create a dice using something that's not" + + " an integer: " + strangs[0] + " and " + + strangs[1] + " are likely culprits."); + } + } + + @Override + public String toString() { + if (nDice instanceof ScalarDie && die instanceof Die) { + return nDice.toString() + die.toString(); + } else { + return "complex[n=" + nDice.toString() + ", d=" + + die.toString() + "]"; + } + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDice.java b/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDice.java index ceb62aa..608174e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDice.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDice.java @@ -40,4 +40,8 @@ public class CompoundDice implements IDiceExpression { return Integer.parseInt(l.roll() + "" + r.roll()); } + @Override + public String toString() { + return "compound[l=" + l.toString() + ", r=" + r.toString() + "]"; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDiceExpression.java b/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDiceExpression.java index 4dd6926..12238c8 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDiceExpression.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/CompoundDiceExpression.java @@ -53,15 +53,21 @@ public class CompoundDiceExpression implements IDiceExpression { return right.roll() * left.roll(); case DIVIDE: /* - * Round to keep results as integers. - * We don't really have any need for floating-point dice + * Round to keep results as integers. We don't really have + * any need for floating-point dice */ return Math.round(right.roll() / left.roll()); default: - throw new IllegalStateException( - "Got passed a invalid ScalarExpressionType " - + det + ". WAT"); + throw new IllegalArgumentException( + "Got passed a invalid ScalarExpressionType " + det + + ". WAT"); } } + + @Override + public String toString() { + return "dice-exp[type=" + det + ", l=" + left.toString() + ", r=" + + right.toString() + "]"; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionBuilder.java b/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionBuilder.java index 6dcd5e3..b1de9ad 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionBuilder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionBuilder.java @@ -20,7 +20,7 @@ public class DiceExpressionBuilder { * @param firstDice * The dice to use as a seed */ - public DiceExpressionBuilder(LazyDice firstDice) { + public DiceExpressionBuilder(ComplexDice firstDice) { baking = firstDice; } @@ -43,7 +43,7 @@ public class DiceExpressionBuilder { * The number of dice in the group */ public DiceExpressionBuilder(int nSides, int nDice) { - baking = new LazyDice(nSides, nDice); + baking = new ComplexDice(nSides, nDice); } /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionParser.java b/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionParser.java index 71801f8..30943e3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionParser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionParser.java @@ -1,7 +1,10 @@ package bjc.utils.dice; +import java.util.Map; import java.util.Stack; +import org.apache.commons.lang3.StringUtils; + import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalStringTokenizer; import bjc.utils.parserutils.ShuntingYard; @@ -20,7 +23,8 @@ public class DiceExpressionParser { * The string to parse an expression from * @return The parsed dice expression */ - public IDiceExpression parse(String exp) { + public IDiceExpression parse(String exp, + Map env) { /* * Create a tokenizer over the strings */ @@ -38,6 +42,8 @@ public class DiceExpressionParser { // size dice groups yard.addOp("c", 6); // compound operator: use for creating compound // dice from expressions + yard.addOp(":=", 0); // binding operator: Bind a name to a variable + // expression /* * Shunt the expression to postfix form @@ -57,16 +63,19 @@ public class DiceExpressionParser { /* * Handle compound dice */ - if (tok.contains("c") && !tok.equalsIgnoreCase("c")) { + if (StringUtils.countMatches(tok, 'c') == 1 + && !tok.equalsIgnoreCase("c")) { String[] strangs = tok.split("c"); - dexps.push(new CompoundDice(LazyDice.fromString(strangs[0]), - LazyDice.fromString(strangs[1]))); - } else if (tok.contains("d") && !tok.equalsIgnoreCase("d")) { + dexps.push(new CompoundDice( + ComplexDice.fromString(strangs[0]), + ComplexDice.fromString(strangs[1]))); + } else if (StringUtils.countMatches(tok, 'd') == 1 + && !tok.equalsIgnoreCase("d")) { /* * Handle dice groups */ - dexps.push(LazyDice.fromString(tok)); + dexps.push(ComplexDice.fromString(tok)); } else { try { /* @@ -75,46 +84,69 @@ public class DiceExpressionParser { dexps.push(new ScalarDie(Integer.parseInt(tok))); } catch (NumberFormatException nfex) { - /* - * Apply an operation to two dice - */ - IDiceExpression l = dexps.pop(); - IDiceExpression r = dexps.pop(); + if (dexps.size() >= 2) { + /* + * Apply an operation to two dice + */ + IDiceExpression r = dexps.pop(); + IDiceExpression l = dexps.pop(); + switch (tok) { + case ":=": + dexps.push( + new BindingDiceExpression( + ((ReferenceDiceExpression) l) + .getName(), + r, env)); + break; + case "+": + dexps.push(new CompoundDiceExpression(r, l, + DiceExpressionType.ADD)); + break; + case "-": + dexps.push(new CompoundDiceExpression(r, l, + DiceExpressionType.SUBTRACT)); + break; + case "*": + dexps.push(new CompoundDiceExpression(r, l, + DiceExpressionType.MULTIPLY)); + break; + case "/": + dexps.push(new CompoundDiceExpression(r, l, + DiceExpressionType.DIVIDE)); + break; + case "c": + dexps.push(new CompoundDice(l, r)); + break; + case "d": + dexps.push(new ComplexDice(l, r)); + break; + default: + /* + * Parse it as a variable reference + * + * Make sure to restore popped variables + */ + dexps.push(l); + dexps.push(r); - switch (tok) { - case "+": - dexps.push(new CompoundDiceExpression(l, r, - DiceExpressionType.ADD)); - break; - case "-": - dexps.push(new CompoundDiceExpression(l, r, - DiceExpressionType.SUBTRACT)); - break; - case "*": - dexps.push(new CompoundDiceExpression(l, r, - DiceExpressionType.MULTIPLY)); - break; - case "/": - dexps.push(new CompoundDiceExpression(l, r, - DiceExpressionType.DIVIDE)); - break; - case "c": - dexps.push(new CompoundDice(l, r)); - break; - case "d": - dexps.push(new LazyDice(l, r)); - break; - default: - /* - * Tell the user the operator is invalid - */ - throw new IllegalStateException( - "Detected invalid operator " + tok); + dexps.push(new ReferenceDiceExpression(tok, + env)); + } + } else { + /* + * Parse it as a variable reference + */ + dexps.push(new ReferenceDiceExpression(tok, env)); } } } }); + if (dexps.size() != 1) { + System.err.println( + "WARNING: Leftovers found on dice expression stack. Remember, := is assignment."); + } + /* * Return the built expression */ diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionType.java b/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionType.java index 150ed51..2259308 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionType.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/DiceExpressionType.java @@ -4,5 +4,22 @@ package bjc.utils.dice; * Enumeration for basic dice expression operators */ public enum DiceExpressionType { - ADD, DIVIDE, MULTIPLY, SUBTRACT + ADD, DIVIDE, MULTIPLY, SUBTRACT; + + public String toString() { + switch (this) { + case ADD: + return "+"; + case DIVIDE: + return "/"; + case MULTIPLY: + return "*"; + case SUBTRACT: + return "-"; + default: + throw new IllegalArgumentException( + "Got passed a invalid ScalarExpressionType " + + this + ". WAT"); + } + }; } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/Die.java b/BJC-Utils2/src/main/java/bjc/utils/dice/Die.java index dc512b4..9fdac14 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/Die.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/Die.java @@ -4,6 +4,7 @@ import java.util.Random; /** * A single polyhedral dice + * * @author ben * */ @@ -11,26 +12,34 @@ public class Die implements IDiceExpression { /** * Random # gen to use for dice */ - private static Random rng = new Random(); - + private static Random rng = new Random(); + /** * Number of sides this die has */ - private int nSides; - + private int nSides; + /** * Create a die with the specified number of sides - * @param nSides The number of sides this dice has + * + * @param nSides + * The number of sides this dice has */ public Die(int nSides) { this.nSides = nSides; } - + /** * Roll this dice once + * * @return The result of rolling the dice */ public int roll() { return rng.nextInt(nSides + 1); } + + @Override + public String toString() { + return "d" + nSides; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/LazyDice.java b/BJC-Utils2/src/main/java/bjc/utils/dice/LazyDice.java deleted file mode 100644 index c1d775f..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/LazyDice.java +++ /dev/null @@ -1,93 +0,0 @@ -package bjc.utils.dice; - -/** - * Implements a collection of one or more of a particular die, where the - * number of dice in the group is variable. - * - * @author ben - * - */ -public class LazyDice implements IDiceExpression { - /** - * The die being rolled - */ - private IDiceExpression die; - - /** - * The number of the specified die to roll - */ - private IDiceExpression nDice; - - /** - * Create a new collection of dice - * - * @param nDce - * The number of dice in the collection - * @param de - * The type of dice the collection is composed of - */ - public LazyDice(IDiceExpression nDce, IDiceExpression de) { - nDice = nDce; - die = de; - } - - /** - * Create a new collection of dice - * - * @param nDce - * The number of dice in the collection - * @param de - * The type of dice the collection is composed of - */ - public LazyDice(int nSides, int de) { - nDice = new ScalarDie(nSides); - die = new Die(de); - } - - @Override - public int roll() { - int res = 0; - - /* - * Add the results of rolling each die - */ - int nRoll = nDice.roll(); - - for (int i = 0; i < nRoll; i++) { - res += die.roll(); - } - - return res; - } - - /** - * Create a dice from a string expression - * - * @param dice - * The string to parse the dice from - * @return A dice group parsed from the string - */ - public static LazyDice fromString(String dice) { - /* - * Split it on the dice type marker - */ - String[] strangs = dice.split("d"); - - try { - /* - * Create the actual dice - */ - return new LazyDice( - new ScalarDie(Integer.parseInt(strangs[0])), - new Die(Integer.parseInt(strangs[1]))); - } catch (NumberFormatException nfex) { - /* - * Tell the user the expression is invalid - */ - throw new IllegalStateException( - "Attempted to create a dice using something that's not" - + " an integer: " + strangs[0] + " and " - + strangs[1] + " are likely culprits."); - } - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/PolyhedralDice.java b/BJC-Utils2/src/main/java/bjc/utils/dice/PolyhedralDice.java index 0ce483a..511fd99 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/PolyhedralDice.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/PolyhedralDice.java @@ -14,8 +14,8 @@ public class PolyhedralDice { * The number of ten-sided dice to produce * @return A group of ten-sided dice of the specified size */ - public static LazyDice d10(int nDice) { - return new LazyDice(nDice, 10); + public static IDiceExpression d10(int nDice) { + return new ComplexDice(nDice, 10); } /** @@ -25,8 +25,8 @@ public class PolyhedralDice { * The number of hundred-sided dice to produce * @return A group of hundred-sided dice of the specified size */ - public static LazyDice d100(int nDice) { - return new LazyDice(nDice, 100); + public static IDiceExpression d100(int nDice) { + return new ComplexDice(nDice, 100); } /** @@ -36,8 +36,8 @@ public class PolyhedralDice { * The number of twelve-sided dice to produce * @return A group of twelve-sided dice of the specified size */ - public static LazyDice d12(int nDice) { - return new LazyDice(nDice, 12); + public static IDiceExpression d12(int nDice) { + return new ComplexDice(nDice, 12); } /** @@ -47,8 +47,8 @@ public class PolyhedralDice { * The number of twenty-sided dice to produce * @return A group of twenty-sided dice of the specified size */ - public static LazyDice d20(int nDice) { - return new LazyDice(nDice, 20); + public static IDiceExpression d20(int nDice) { + return new ComplexDice(nDice, 20); } /** @@ -58,8 +58,8 @@ public class PolyhedralDice { * The number of ten-sided dice to produce * @return A group of ten-sided dice of the specified size */ - public static LazyDice d4(int nDice) { - return new LazyDice(nDice, 4); + public static IDiceExpression d4(int nDice) { + return new ComplexDice(nDice, 4); } /** @@ -69,8 +69,8 @@ public class PolyhedralDice { * The number of ten-sided dice to produce * @return A group of ten-sided dice of the specified size */ - public static LazyDice d6(int nDice) { - return new LazyDice(nDice, 6); + public static IDiceExpression d6(int nDice) { + return new ComplexDice(nDice, 6); } /** @@ -80,7 +80,7 @@ public class PolyhedralDice { * The number of ten-sided dice to produce * @return A group of ten-sided dice of the specified size */ - public static LazyDice d8(int nDice) { - return new LazyDice(nDice, 8); + public static IDiceExpression d8(int nDice) { + return new ComplexDice(nDice, 8); } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ReferenceDiceExpression.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ReferenceDiceExpression.java new file mode 100644 index 0000000..d8062da --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ReferenceDiceExpression.java @@ -0,0 +1,60 @@ +package bjc.utils.dice; + +import java.util.Map; + +/** + * A dice expression that refers to a variable bound in a mutable + * enviroment + * + * @author ben + * + */ +public class ReferenceDiceExpression implements IDiceExpression { + /** + * The name of the bound variable + */ + private String name; + + /** + * The enviroment to do variable dereferencing against + */ + private Map env; + + /** + * Create a new reference dice expression referring to the given name + * in an enviroment + * + * @param name + * The name of the bound variable + * @param env + * The enviroment to resolve the variable against + */ + public ReferenceDiceExpression(String name, + Map env) { + this.name = name; + this.env = env; + } + + @Override + public int roll() { + return env.get(name).roll(); + } + + @Override + public String toString() { + if (env.containsKey(name)) { + return env.get(name).toString(); + } else { + return name; + } + } + + /** + * Get the name of the referenced variable + * + * @return the name of the referenced variable + */ + public String getName() { + return name; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDiceExpression.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDiceExpression.java index 205c216..2b174c8 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDiceExpression.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDiceExpression.java @@ -23,9 +23,13 @@ public class ScalarDiceExpression implements IDiceExpression { /** * Create a dice expression with a scalar - * @param dex The dice to use - * @param scalr The scalar to use - * @param dt The operation to combine with + * + * @param dex + * The dice to use + * @param scalr + * The scalar to use + * @param dt + * The operation to combine with */ public ScalarDiceExpression(IDiceExpression dex, int scalr, DiceExpressionType dt) { @@ -51,4 +55,10 @@ public class ScalarDiceExpression implements IDiceExpression { + det); } } + + @Override + public String toString() { + return "scalar-exp[type=" + det + ", l=" + scalar + ", r=" + + exp.toString() + "]"; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDie.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDie.java index dde09b4..bef68e1 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDie.java +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ScalarDie.java @@ -2,6 +2,7 @@ package bjc.utils.dice; /** * A die that represents a static number + * * @author ben * */ @@ -18,10 +19,17 @@ public class ScalarDie implements IDiceExpression { /** * Create a dice with the specified number - * @param num The number used for the dice + * + * @param num + * The number used for the dice */ public ScalarDie(int num) { this.num = num; } + @Override + public String toString() { + return Integer.toString(num); + } + } -- cgit v1.2.3