m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--__tests__/dice.test.js19
-rw-r--r--__tests__/lexer.test.js10
-rw-r--r--__tests__/parser.test.js10
-rw-r--r--index.js2
-rw-r--r--src/dice.js16
-rw-r--r--src/lexer.js1
-rw-r--r--src/parser.js1
7 files changed, 59 insertions, 0 deletions
diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js
index 12d9130..d4e2802 100644
--- a/__tests__/dice.test.js
+++ b/__tests__/dice.test.js
@@ -8,6 +8,7 @@ const {
bonusSubtract,
negative,
explode,
+ explodeUnder,
keepHigh,
keepLow,
again,
@@ -483,6 +484,24 @@ describe('exploding dice', () => {
}
})
})
+
+ describe('1e1d6', () => {
+ const die = explodeUnder(constant(1), d(constant(1), constant(6)))
+ testDie(die, {
+ diceCount: 1,
+ average: {
+ average: 4.2
+ },
+ variance: {
+ variance: 2.24
+ },
+ bounds: {
+ low: 2,
+ expectLow: true,
+ high: Infinity
+ }
+ })
+ })
})
describe('keep', () => {
diff --git a/__tests__/lexer.test.js b/__tests__/lexer.test.js
index 21ae3b0..0336f44 100644
--- a/__tests__/lexer.test.js
+++ b/__tests__/lexer.test.js
@@ -148,6 +148,16 @@ describe('lex', () => {
{ type: 'constant', value: 6 }
])
})
+
+ test('1e1d6', () => {
+ expect(lex('1e1d6')).toEqual([
+ { type: 'constant', value: 1 },
+ { type: 'e' },
+ { type: 'constant', value: 1 },
+ { type: 'd' },
+ { type: 'constant', value: 6 }
+ ])
+ })
})
describe('keep', () => {
diff --git a/__tests__/parser.test.js b/__tests__/parser.test.js
index 70ad98d..765388d 100644
--- a/__tests__/parser.test.js
+++ b/__tests__/parser.test.js
@@ -173,6 +173,16 @@ describe('parse', () => {
right: { type: 'constant', value: 6 }
}
})
+
+ expect(parse('1e1d6')).toEqual({
+ type: 'e',
+ left: { type: 'constant', value: 1 },
+ right: {
+ type: 'd',
+ left: { type: 'constant', value: 1 },
+ right: { type: 'constant', value: 6 }
+ }
+ })
})
it('parses dice with keep high', () => {
diff --git a/index.js b/index.js
index e117b7c..8c52ad1 100644
--- a/index.js
+++ b/index.js
@@ -9,6 +9,8 @@ const interpret = tree => {
return D.d(interpret(tree.left), interpret(tree.right))
case 'E':
return D.explode(interpret(tree.left), interpret(tree.right))
+ case 'e':
+ return D.explodeUnder(interpret(tree.left), interpret(tree.right))
case 'K':
return D.keepHigh(interpret(tree.left), interpret(tree.right))
case 'k':
diff --git a/src/dice.js b/src/dice.js
index 9bc53d7..e96aca9 100644
--- a/src/dice.js
+++ b/src/dice.js
@@ -73,6 +73,21 @@ const explode = (die1, die2) => {
}
}
+const explodeUnder = (die1, die2) => {
+ return () => {
+ const explodeOn = roll(die1)
+ return die2().map(die => () => {
+ let lastRoll = die()
+ let total = lastRoll
+ while (lastRoll <= explodeOn) {
+ lastRoll = die()
+ total += lastRoll
+ }
+ return total
+ })
+ }
+}
+
const keepHigh = (die1, die2) => {
return () => {
const numberToKeep = roll(die1)
@@ -174,6 +189,7 @@ exports.bonusAdd = bonusAdd
exports.bonusSubtract = bonusSubtract
exports.negative = negative
exports.explode = explode
+exports.explodeUnder = explodeUnder
exports.keepHigh = keepHigh
exports.keepLow = keepLow
exports.again = again
diff --git a/src/lexer.js b/src/lexer.js
index f316147..7eb95b0 100644
--- a/src/lexer.js
+++ b/src/lexer.js
@@ -23,6 +23,7 @@ newLexemeType('minus', '-')
newLexemeType('(', '\\(')
newLexemeType(')', '\\)')
newLexemeType('E', 'E')
+newLexemeType('e', 'e')
newLexemeType('K', 'K')
newLexemeType('k', 'k')
newLexemeType('A', 'A')
diff --git a/src/parser.js b/src/parser.js
index 0201d05..124d686 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -61,6 +61,7 @@ newSymbol('d', (parser) => {
}
})
newDieOperation('E')
+newDieOperation('e')
newDieOperation('K')
newDieOperation('k')
newDieOperation('A')