diff options
| -rw-r--r-- | __tests__/dice.test.js | 24 | ||||
| -rw-r--r-- | __tests__/lexer.test.js | 10 | ||||
| -rw-r--r-- | __tests__/parser.test.js | 10 | ||||
| -rw-r--r-- | index.js | 2 | ||||
| -rw-r--r-- | src/dice.js | 37 | ||||
| -rw-r--r-- | src/lexer.js | 1 | ||||
| -rw-r--r-- | src/parser.js | 1 | 
7 files changed, 85 insertions, 0 deletions
| diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js index d4e2802..272f436 100644 --- a/__tests__/dice.test.js +++ b/__tests__/dice.test.js @@ -12,6 +12,7 @@ const {    keepHigh,    keepLow,    again, +  againUnder,    threshold  } = require('../src/dice.js') @@ -579,6 +580,29 @@ describe('again', () => {        }      })    }) + +  describe('1a1d6', () => { +    const die = againUnder(constant(1), d(constant(1), constant(6))) + +    testDie(die, { +      variableDiceCount: { +        min: 1, +        max: Infinity +      }, +      average: { +        average: 4.2 +      }, +      variance: { +        variance: 2.24 +      }, +      bounds: { +        low: 2, +        high: Infinity, +        expectLow: true, +        expectHigh: false +      } +    }) +  })  })  describe('threshold', () => { diff --git a/__tests__/lexer.test.js b/__tests__/lexer.test.js index 0336f44..25ef816 100644 --- a/__tests__/lexer.test.js +++ b/__tests__/lexer.test.js @@ -203,6 +203,16 @@ describe('lex', () => {          { type: 'constant', value: 6 }        ])      }) + +    test('6a3d6', () => { +      expect(lex('6a3d6')).toEqual([ +        { type: 'constant', value: 6 }, +        { type: 'a' }, +        { type: 'constant', value: 3 }, +        { type: 'd' }, +        { type: 'constant', value: 6 } +      ]) +    })    })    describe('threshold', () => { diff --git a/__tests__/parser.test.js b/__tests__/parser.test.js index 765388d..ad67fc4 100644 --- a/__tests__/parser.test.js +++ b/__tests__/parser.test.js @@ -219,6 +219,16 @@ describe('parse', () => {          right: { type: 'constant', value: 10 }        }      }) + +    expect(parse('10a3d10')).toEqual({ +      type: 'a', +      left: { type: 'constant', value: 10 }, +      right: { +        type: 'd', +        left: { type: 'constant', value: 3 }, +        right: { type: 'constant', value: 10 } +      } +    })    })    it('parases dice with threshold', () => { @@ -17,6 +17,8 @@ const interpret = tree => {      return D.keepLow(interpret(tree.left), interpret(tree.right))    case 'A':      return D.again(interpret(tree.left), interpret(tree.right)) +  case 'a': +    return D.againUnder(interpret(tree.left), interpret(tree.right))    case 'T':      return D.threshold(interpret(tree.left), interpret(tree.right))    case 'add': diff --git a/src/dice.js b/src/dice.js index e96aca9..e580c9d 100644 --- a/src/dice.js +++ b/src/dice.js @@ -162,6 +162,42 @@ const again = (die1, die2) => {    }  } +const againUnder = (die1, die2) => { +  return () => { +    const againOn = roll(die1) +    let rolls = [] +    let rollAgain = [] + +    const rollDie = (die) => { +      const roll = die() + +      if (roll <= againOn) { +        rollAgain.push(die) +      } + +      let returnedOriginal = false +      rolls.push(() => { +        if (!returnedOriginal) { +          returnedOriginal = true +          return roll +        } else { +          return die() +        } +      }) +    } + +    die2().forEach(rollDie) + +    while (rollAgain.length > 0) { +      const oldRollAgain = rollAgain +      rollAgain = [] +      oldRollAgain.forEach(rollDie) +    } + +    return rolls +  } +} +  const threshold = (die1, die2) => {    return () => {      const cutoff = roll(die1) @@ -193,4 +229,5 @@ exports.explodeUnder = explodeUnder  exports.keepHigh = keepHigh  exports.keepLow = keepLow  exports.again = again +exports.againUnder = againUnder  exports.threshold = threshold diff --git a/src/lexer.js b/src/lexer.js index 7eb95b0..f33dc87 100644 --- a/src/lexer.js +++ b/src/lexer.js @@ -27,6 +27,7 @@ newLexemeType('e', 'e')  newLexemeType('K', 'K')  newLexemeType('k', 'k')  newLexemeType('A', 'A') +newLexemeType('a', 'a')  newLexemeType('T', 'T')  const lex = (expressionString) => { diff --git a/src/parser.js b/src/parser.js index 124d686..f8e2a5b 100644 --- a/src/parser.js +++ b/src/parser.js @@ -65,6 +65,7 @@ newDieOperation('e')  newDieOperation('K')  newDieOperation('k')  newDieOperation('A') +newDieOperation('a')  newDieOperation('T')  newInfix('bigPlus', 20, { type: 'add' }) |