From 7efea0582dda35cd7dc0c370ef3b56c84b2f2291 Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Wed, 30 Aug 2017 16:25:34 -0400 Subject: Implement explode under --- __tests__/dice.test.js | 19 +++++++++++++++++++ __tests__/lexer.test.js | 10 ++++++++++ __tests__/parser.test.js | 10 ++++++++++ index.js | 2 ++ src/dice.js | 16 ++++++++++++++++ src/lexer.js | 1 + src/parser.js | 1 + 7 files changed, 59 insertions(+) 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') -- cgit v1.2.3