1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
package bjc.dicelang.dice;
import java.util.Random;
import java.util.function.Predicate;
import java.util.regex.Pattern;
public class DiceBox {
static final Random rng = new Random();
public static DieExpression parseExpression(String exp) {
if(!isValidExpression(exp)) return null;
if(scalarDiePattern.matcher(exp).matches()) {
Die scal = new ScalarDie(Long.parseLong(exp.substring(0, exp.indexOf('s'))));
return new DieExpression(scal);
} else if(simpleDiePattern.matcher(exp).matches()) {
String[] dieParts = exp.split("d");
long right = Long.parseLong(dieParts[1]);
if(dieParts[0].equals("")) {
Die scal = new SimpleDie(1, right);
return new DieExpression(scal);
} else {
Die scal = new SimpleDie(Long.parseLong(dieParts[0]), right);
return new DieExpression(scal);
}
} else if(fudgeDiePattern.matcher(exp).matches()) {
String nDice = exp.substring(0, exp.indexOf('d'));
return new DieExpression(new FudgeDie(Long.parseLong(nDice)));
} else if(compoundDiePattern.matcher(exp).matches()) {
String[] dieParts = exp.split("c");
DieExpression left = parseExpression(dieParts[0]);
DieExpression right = parseExpression(dieParts[1]);
return new DieExpression(new CompoundDie(left.scalar, right.scalar));
} else if(compoundingDiePattern.matcher(exp).matches()) {
String[] dieParts = exp.split("!!");
DieExpression left = parseExpression(dieParts[0]);
Predicate<Long> right = deriveCond(dieParts[1]);
Die scal = new CompoundingDie(left.scalar, right, dieParts[1]);
return new DieExpression(scal);
} else if(explodingDiePattern.matcher(exp).matches()) {
String[] dieParts = exp.split("!");
DieExpression left = parseExpression(dieParts[0]);
Predicate<Long> right = deriveCond(dieParts[1]);
DieList lst = new ExplodingDice(left.scalar, right, dieParts[1], false);
return new DieExpression(lst);
} else if(penetratingDiePattern.matcher(exp).matches()) {
String[] dieParts = exp.split("p!");
DieExpression left = parseExpression(dieParts[0]);
Predicate<Long> right = deriveCond(dieParts[1]);
DieList lst = new ExplodingDice(left.scalar, right, dieParts[1], true);
return new DieExpression(lst);
} else if(diceListPattern.matcher(exp).matches()) {
String[] dieParts = exp.split("dl");
DieExpression left = parseExpression(dieParts[0]);
DieExpression right = parseExpression(dieParts[1]);
DieList lst = new SimpleDieList(left.scalar, right.scalar);
return new DieExpression(lst);
}
// @TODO give a specific error message
return null;
}
private static final String comparePoint = "[<>=]\\d+";
private static final String scalarDie = "[\\+\\-]?\\d+sd";
private static final Pattern scalarDiePattern = Pattern.compile("\\A" + scalarDie + "\\Z");
private static final String simpleDie = "(?:\\d+)?d\\d+";
private static final Pattern simpleDiePattern = Pattern.compile("\\A" + simpleDie + "\\Z");
private static final String fudgeDie = "(?:\\d+)?dF";
private static final Pattern fudgeDiePattern = Pattern.compile("\\A" + fudgeDie + "\\Z");
private static final String compoundDie = simpleDie + "c(?:(?:" + simpleDie + ")|(?:\\d+))";
private static final Pattern compoundDiePattern = Pattern.compile("\\A" + compoundDie + "\\Z");
private static final String compoundGroup = "(?:(?:" + scalarDie + ")|(?:" + simpleDie + ")|(?:"
+ compoundDie + ")|(?:" + fudgeDie +"))";
private static final String compoundingDie = compoundGroup + "!!" + comparePoint;
private static final Pattern compoundingDiePattern = Pattern.compile("\\A" + compoundingDie + "\\Z");
private static final String explodingDie = compoundGroup + "!" + comparePoint;
private static final Pattern explodingDiePattern = Pattern.compile("\\A" + explodingDie + "\\Z");
private static final String penetratingDie = compoundGroup + "!" + comparePoint;
private static final Pattern penetratingDiePattern = Pattern.compile("\\A" + penetratingDie + "\\Z");
private static final String diceList = compoundGroup + "dl" + compoundGroup;
private static final Pattern diceListPattern = Pattern.compile("\\A" + diceList + "\\Z");
public static boolean isValidExpression(String exp) {
if(scalarDiePattern.matcher(exp).matches()) {
return true;
} else if(simpleDiePattern.matcher(exp).matches()) {
return true;
} else if(fudgeDiePattern.matcher(exp).matches()) {
return true;
} else if(compoundDiePattern.matcher(exp).matches()) {
return true;
} else if(compoundingDiePattern.matcher(exp).matches()) {
return true;
} else if(explodingDiePattern.matcher(exp).matches()) {
return true;
} else if(penetratingDiePattern.matcher(exp).matches()) {
return true;
} else if (diceListPattern.matcher(exp).matches()) {
return true;
} else {
return false;
}
}
private static Predicate<Long> deriveCond(String patt) {
long num = Long.parseLong(patt.substring(1));
switch(patt.charAt(0)) {
case '<':
return (roll) -> roll < num;
case '=':
return (roll) -> roll == num;
case '>':
return (roll) -> roll > num;
default:
return (roll) -> false;
}
}
}
|