diff options
| -rw-r--r-- | __tests__/dice.test.js | 45 | ||||
| -rw-r--r-- | __tests__/lexer.test.js | 12 | ||||
| -rw-r--r-- | __tests__/parser.test.js | 16 | ||||
| -rw-r--r-- | index.js | 2 | ||||
| -rw-r--r-- | src/dice.js | 14 | ||||
| -rw-r--r-- | src/lexer.js | 1 | ||||
| -rw-r--r-- | src/parser.js | 2 | 
7 files changed, 91 insertions, 1 deletions
| diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js index d397d4c..6a9ba46 100644 --- a/__tests__/dice.test.js +++ b/__tests__/dice.test.js @@ -16,7 +16,8 @@ const {    againAbove,    againUnder,    thresholdHigh, -  thresholdLow +  thresholdLow, +  repeat  } = require('../src/dice.js')  const defaultNumberRolls = 500 @@ -692,3 +693,45 @@ describe('threshold', () => {      })    })  }) + +describe('repeat', () => { +  describe('1d6 x 2', () => { +    const die = repeat(d(constant(1), constant(6)), constant(2)) + +    testDie(die, { +      diceCount: 2, +      average: { +        average: 7 +      }, +      variance: { +        variance: 5.83 +      }, +      bounds: { +        low: 2, +        high: 12, +        expectLow: true, +        expectHigh: true +      } +    }) +  }) + +  describe('1d6 x 1d4', () => { +    const die = repeat(d(constant(1), constant(6)), d(constant(1), constant(4))) + +    testDie(die, { +      variableDiceCount: { +        min: 1, +        max: 4 +      }, +      average: { +        average: 8.75 +      }, +      bounds: { +        low: 1, +        high: 24, +        expectLow: true, +        expectHigh: false +      } +    }) +  }) +}) diff --git a/__tests__/lexer.test.js b/__tests__/lexer.test.js index 0c615d5..6745715 100644 --- a/__tests__/lexer.test.js +++ b/__tests__/lexer.test.js @@ -284,4 +284,16 @@ describe('lex', () => {        ])      })    }) + +  describe('repeat', () => { +    test('1d6 x 3', () => { +      expect(lex('1d6 x 3')).toEqual([ +        { type: 'constant', value: 1 }, +        { type: 'd' }, +        { type: 'constant', value: 6 }, +        { type: ' x ' }, +        { type: 'constant', value: 3 } +      ]) +    }) +  })  }) diff --git a/__tests__/parser.test.js b/__tests__/parser.test.js index bef11c5..d696b3e 100644 --- a/__tests__/parser.test.js +++ b/__tests__/parser.test.js @@ -285,6 +285,22 @@ describe('parse', () => {      })    }) +  it('parses dice with repeat', () => { +    expect(parse('1d6 x 1d4')).toEqual({ +      type: 'repeat', +      left: { +        type: 'd', +        left: { type: 'constant', value: 1 }, +        right: { type: 'constant', value: 6 } +      }, +      right: { +        type: 'd', +        left: { type: 'constant', value: 1 }, +        right: { type: 'constant', value: 4 } +      } +    }) +  }) +    describe('parsing parentheses', () => {      test('(1d6)d6', () => {        expect(parse('(1d6)d6')).toEqual({ @@ -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 'repeat': +    return D.repeat(interpret(tree.left), interpret(tree.right))    }  } diff --git a/src/dice.js b/src/dice.js index d47455e..5a484b0 100644 --- a/src/dice.js +++ b/src/dice.js @@ -193,6 +193,19 @@ const thresholdLow = (die1, die2) => {    return threshold(lessThanOrEqual, die1, die2)  } +const repeat = (die1, die2) => { +  return () => { +    const times = roll(die2) + +    let results = [] +    for (let i = 0; i < times; i++) { +      results = results.concat(die1()) +    } + +    return results +  } +} +  exports.pool = pool  exports.roll = roll  exports.constant = constant @@ -212,3 +225,4 @@ exports.againAbove = againAbove  exports.againUnder = againUnder  exports.thresholdHigh = thresholdHigh  exports.thresholdLow = thresholdLow +exports.repeat = repeat diff --git a/src/lexer.js b/src/lexer.js index 59fba16..248a9b2 100644 --- a/src/lexer.js +++ b/src/lexer.js @@ -32,6 +32,7 @@ newLexemeType('A', 'A')  newLexemeType('a', 'a')  newLexemeType('T', 'T')  newLexemeType('t', 't') +newLexemeType(' x ', ' x ')  const lex = (expressionString) => {    let lexemes = [] diff --git a/src/parser.js b/src/parser.js index fd0fd59..b1f6ebb 100644 --- a/src/parser.js +++ b/src/parser.js @@ -82,6 +82,8 @@ newSymbol('minus', (parser) => {    }  }) +newInfix(' x ', 24, { type: 'repeat' }) +  newSymbol('end', null, -1)  const newParser = (tokens) => { |