diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | __tests__/dice.test.js | 43 | ||||
-rw-r--r-- | __tests__/parser.test.js | 12 | ||||
-rw-r--r-- | index.js | 2 | ||||
-rw-r--r-- | src/dice.js | 10 | ||||
-rw-r--r-- | src/parser.js | 1 |
6 files changed, 68 insertions, 1 deletions
@@ -102,6 +102,7 @@ Semantics are defined in terms of the `pool` function. * `D - E` is equivalent to `D + (-E)`. * `D+E` is the additive bonus operation. For each die in `D`'s pool, the die is rolled and `roll(E)` is added to its result. +* `D-E` is equivalent to `D+(-E)`. * `DEF` (here `E` is the literal symbol `E`, `D` and `F` are dice expressions) is an "exploding die." First `D` is rolled. Now each die in the dice pool generated by `F` is rolled repeatedly until it rolls something less than the diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js index 3073fee..6ff86e7 100644 --- a/__tests__/dice.test.js +++ b/__tests__/dice.test.js @@ -8,7 +8,8 @@ const { explode, keepHigh, keepLow, - bonusAdd + bonusAdd, + bonusSubtract } = require('../src/dice.js') const defaultNumberRolls = 500 @@ -493,3 +494,43 @@ describe('bonusAdd', () => { }) }) }) + +describe('bonusSubtract', () => { + describe('1d20-3', () => { + const die = bonusSubtract(d(constant(1), constant(20)), constant(3)) + testDie(die, { + diceCount: 1, + average: { + average: 7.5 + }, + variance: { + variance: 33.25 + }, + bounds: { + low: -2, + high: 17, + expectLow: true, + expectHigh: true + } + }) + }) + + describe('3d4-1', () => { + const die = bonusSubtract(d(constant(3), constant(4)), constant(1)) + testDie(die, { + diceCount: 3, + average: { + average: 4.5 + }, + variance: { + variance: 3.75 + }, + bounds: { + low: 0, + high: 9, + expectLow: true, + expectHigh: true + } + }) + }) +}) diff --git a/__tests__/parser.test.js b/__tests__/parser.test.js index 873972b..54e1da7 100644 --- a/__tests__/parser.test.js +++ b/__tests__/parser.test.js @@ -163,6 +163,18 @@ describe('parse', () => { }) }) + it('parses negative bonuses', () => { + expect(parse('3d4-1')).toEqual({ + type: 'bonusSubtract', + left: { + type: 'd', + left: { type: 'constant', value: 3 }, + right: { type: 'constant', value: 4 } + }, + right: { type: 'constant', value: 1 } + }) + }) + describe('parsing parentheses', () => { test('(1d6)d6', () => { expect(parse('(1d6)d6')).toEqual({ @@ -21,6 +21,8 @@ const interpret = tree => { return D.negative(interpret(tree.value)) case 'bonusAdd': return D.bonusAdd(interpret(tree.left), interpret(tree.right)) + case 'bonusSubtract': + return D.bonusSubtract(interpret(tree.left), interpret(tree.right)) } } diff --git a/src/dice.js b/src/dice.js index becf7dc..58467c4 100644 --- a/src/dice.js +++ b/src/dice.js @@ -102,6 +102,15 @@ const bonusAdd = (die1, die2) => { } } +const bonusSubtract = (die1, die2) => { + const negative2 = negative(die2) + return () => { + return die1().map(die => { + return () => die() + roll(negative2) + }) + } +} + exports.pool = pool exports.roll = roll exports.constant = constant @@ -113,3 +122,4 @@ exports.explode = explode exports.keepHigh = keepHigh exports.keepLow = keepLow exports.bonusAdd = bonusAdd +exports.bonusSubtract = bonusSubtract diff --git a/src/parser.js b/src/parser.js index 48de2ab..244cdd1 100644 --- a/src/parser.js +++ b/src/parser.js @@ -66,6 +66,7 @@ newDieOperation('k') newInfix('bigPlus', 20, { type: 'add' }) newInfix('plus', 20, { type: 'bonusAdd' }) +newInfix('minus', 20, { type: 'bonusSubtract' }) newInfix('bigMinus', 20, { type: 'subtract' }) newSymbol('minus', (parser) => { return { |