From 83983efa99d910a97a72fc8b00dd9d7eb8829368 Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Tue, 5 Sep 2017 22:29:24 -0400 Subject: Implement multiplicative bonuses --- __tests__/dice.test.js | 41 +++++++++++++++++++++++++++++++++++++++++ __tests__/lexer.test.js | 12 ++++++++++++ __tests__/parser.test.js | 12 ++++++++++++ index.js | 2 ++ src/dice.js | 9 +++++++++ src/lexer.js | 1 + src/parser.js | 1 + 7 files changed, 78 insertions(+) diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js index 6a9ba46..375c9ad 100644 --- a/__tests__/dice.test.js +++ b/__tests__/dice.test.js @@ -8,6 +8,7 @@ const { divide, bonusAdd, bonusSubtract, + bonusMultiply, negative, explodeAbove, explodeUnder, @@ -462,6 +463,46 @@ describe('bonusSubtract', () => { }) }) +describe('bonusMultiply', () => { + describe('1d20*3', () => { + const die = bonusMultiply(d(constant(1), constant(20)), constant(3)) + testDie(die, { + diceCount: 1, + average: { + average: 31.5 + }, + variance: { + variance: 299.25 + }, + bounds: { + low: 3, + high: 60, + expectLow: true, + expectHigh: true + } + }) + }) + + describe('3d4*2', () => { + const die = bonusMultiply(d(constant(3), constant(4)), constant(2)) + testDie(die, { + diceCount: 3, + average: { + average: 15 + }, + variance: { + variance: 15 + }, + bounds: { + low: 6, + high: 24, + expectLow: true, + expectHigh: true + } + }) + }) +}) + describe('negative', () => { describeBasicDie(1, 6, defaultNumberRolls, true) describeBasicDie(0, 6, defaultNumberRolls, true) diff --git a/__tests__/lexer.test.js b/__tests__/lexer.test.js index 6745715..31150bc 100644 --- a/__tests__/lexer.test.js +++ b/__tests__/lexer.test.js @@ -241,6 +241,18 @@ describe('lex', () => { }) }) + describe('bonusMultiply', () => { + test('3d4*1', () => { + expect(lex('3d4*1')).toEqual([ + { type: 'constant', value: 3 }, + { type: 'd' }, + { type: 'constant', value: 4 }, + { type: 'times' }, + { type: 'constant', value: 1 } + ]) + }) + }) + describe('again', () => { test('6A3d6', () => { expect(lex('6A3d6')).toEqual([ diff --git a/__tests__/parser.test.js b/__tests__/parser.test.js index d696b3e..5580b4c 100644 --- a/__tests__/parser.test.js +++ b/__tests__/parser.test.js @@ -153,6 +153,18 @@ describe('parse', () => { }) }) + it('parses multiplicative bonuses', () => { + expect(parse('3d4*1')).toEqual({ + type: 'bonusMultiply', + left: { + type: 'd', + left: { type: 'constant', value: 3 }, + right: { type: 'constant', value: 4 } + }, + right: { type: 'constant', value: 1 } + }) + }) + test('bonus binds stronger than addition', () => { expect(parse('2d6 + 2d6+2d6')).toEqual({ type: 'add', diff --git a/index.js b/index.js index cc768cb..4a0d942 100644 --- a/index.js +++ b/index.js @@ -37,6 +37,8 @@ const interpret = tree => { return D.bonusAdd(interpret(tree.left), interpret(tree.right)) case 'bonusSubtract': return D.bonusSubtract(interpret(tree.left), interpret(tree.right)) + case 'bonusMultiply': + return D.bonusMultiply(interpret(tree.left), interpret(tree.right)) case 'repeat': return D.repeat(interpret(tree.left), interpret(tree.right)) } diff --git a/src/dice.js b/src/dice.js index 5a484b0..6351929 100644 --- a/src/dice.js +++ b/src/dice.js @@ -73,6 +73,14 @@ const bonusSubtract = (die1, die2) => { } } +const bonusMultiply = (die1, die2) => { + return () => { + return die1().map(die => { + return () => die() * roll(die2) + }) + } +} + const explode = (comparison, die1, die2) => { return () => { const explodeOn = roll(die1) @@ -216,6 +224,7 @@ exports.multiply = multiply exports.divide = divide exports.bonusAdd = bonusAdd exports.bonusSubtract = bonusSubtract +exports.bonusMultiply = bonusMultiply exports.negative = negative exports.explodeAbove = explodeAbove exports.explodeUnder = explodeUnder diff --git a/src/lexer.js b/src/lexer.js index 248a9b2..e700f87 100644 --- a/src/lexer.js +++ b/src/lexer.js @@ -22,6 +22,7 @@ newLexemeType('bigTimes', ' \\* ') newLexemeType('bigDivide', ' / ') newLexemeType('plus', '\\+') newLexemeType('minus', '-') +newLexemeType('times', '\\*') newLexemeType('(', '\\(') newLexemeType(')', '\\)') newLexemeType('E', 'E') diff --git a/src/parser.js b/src/parser.js index b1f6ebb..54dc0ae 100644 --- a/src/parser.js +++ b/src/parser.js @@ -75,6 +75,7 @@ newInfix('bigTimes', 23, { type: 'multiply' }) newInfix('bigDivide', 23, { type: 'divide' }) newInfix('plus', 25, { type: 'bonusAdd' }) newInfix('minus', 25, { type: 'bonusSubtract' }) +newInfix('times', 26, { type: 'bonusMultiply' }) newSymbol('minus', (parser) => { return { type: 'negative', -- cgit v1.2.3