diff options
| -rw-r--r-- | __tests__/dice.test.js | 14 | ||||
| -rw-r--r-- | index.js | 6 | ||||
| -rw-r--r-- | src/dice.js | 121 | 
3 files changed, 46 insertions, 95 deletions
| diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js index fb8a155..caba0a9 100644 --- a/__tests__/dice.test.js +++ b/__tests__/dice.test.js @@ -7,13 +7,13 @@ const {    bonusAdd,    bonusSubtract,    negative, -  explode, +  explodeAbove,    explodeUnder,    keepHigh,    keepLow, -  again, +  againAbove,    againUnder, -  threshold, +  thresholdHigh,    thresholdLow  } = require('../src/dice.js') @@ -452,7 +452,7 @@ describe('compound dice', () => {  describe('exploding dice', () => {    describe('6E1d6', () => { -    const die = explode(constant(6), d(constant(1), constant(6))) +    const die = explodeAbove(constant(6), d(constant(1), constant(6)))      testDie(die, {        diceCount: 1,        average: { @@ -470,7 +470,7 @@ describe('exploding dice', () => {    })    describe('6E2d6', () => { -    const die = explode(constant(6), d(constant(2), constant(6))) +    const die = explodeAbove(constant(6), d(constant(2), constant(6)))      testDie(die, {        diceCount: 2,        average: { @@ -560,7 +560,7 @@ describe('keep', () => {  describe('again', () => {    describe('10A1d10', () => { -    const die = again(constant(10), d(constant(1), constant(10))) +    const die = againAbove(constant(10), d(constant(1), constant(10)))      testDie(die, {        variableDiceCount: { @@ -608,7 +608,7 @@ describe('again', () => {  describe('threshold', () => {    describe('8T3d10', () => { -    const die = threshold(constant(8), d(constant(3), constant(10))) +    const die = thresholdHigh(constant(8), d(constant(3), constant(10)))      testDie(die, {        diceCount: 3, @@ -8,7 +8,7 @@ const interpret = tree => {    case 'd':      return D.d(interpret(tree.left), interpret(tree.right))    case 'E': -    return D.explode(interpret(tree.left), interpret(tree.right)) +    return D.explodeAbove(interpret(tree.left), interpret(tree.right))    case 'e':      return D.explodeUnder(interpret(tree.left), interpret(tree.right))    case 'K': @@ -16,11 +16,11 @@ const interpret = tree => {    case 'k':      return D.keepLow(interpret(tree.left), interpret(tree.right))    case 'A': -    return D.again(interpret(tree.left), interpret(tree.right)) +    return D.againAbove(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)) +    return D.thresholdHigh(interpret(tree.left), interpret(tree.right))    case 't':      return D.thresholdLow(interpret(tree.left), interpret(tree.right))    case 'add': diff --git a/src/dice.js b/src/dice.js index 53d337d..828a772 100644 --- a/src/dice.js +++ b/src/dice.js @@ -1,3 +1,6 @@ +const greaterThanOrEqual = (a, b) => a >= b +const lessThanOrEqual = (a, b) => a <= b +  const constant = n => () => [() => n]  const pool = (die) => { @@ -58,13 +61,13 @@ const bonusSubtract = (die1, die2) => {    }  } -const explode = (die1, die2) => { +const explode = (comparison, die1, die2) => {    return () => {      const explodeOn = roll(die1)      return die2().map(die => () => {        let lastRoll = die()        let total = lastRoll -      while (lastRoll >= explodeOn) { +      while (comparison(lastRoll, explodeOn)) {          lastRoll = die()          total += lastRoll        } @@ -73,26 +76,21 @@ const explode = (die1, die2) => {    }  } +const explodeAbove = (die1, die2) => { +  return explode(greaterThanOrEqual, 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 -    }) -  } +  return explode(lessThanOrEqual, die1, die2)  } -const keepHigh = (die1, die2) => { + + +const keep = (order, die1, die2) => {    return () => {      const numberToKeep = roll(die1)      let rolls = die2().map(die => [die, die()]) -    rolls.sort((a, b) => (a[1] - b[1])).reverse() +    rolls.sort(order)      return rolls.slice(0, numberToKeep).map(pair => {        let returnedOriginal = false        return () => { @@ -107,26 +105,15 @@ const keepHigh = (die1, die2) => {    }  } +const keepHigh = (die1, die2) => { +  return keep((a, b) => (b[1] - a[1]), die1, die2) +} +  const keepLow = (die1, die2) => { -  return () => { -    const numberToKeep = roll(die1) -    let rolls = die2().map(die => [die, die()]) -    rolls.sort((a, b) => (a[1] - b[1])) -    return rolls.slice(0, numberToKeep).map(pair => { -      let returnedOriginal = false -      return () => { -        if (!returnedOriginal) { -          returnedOriginal = true -          return pair[1] -        } else { -          return pair[0]() -        } -      } -    }) -  } +  return keep((a, b) => (a[1] - b[1]), die1, die2)  } -const again = (die1, die2) => { +const again = (comparison, die1, die2) => {    return () => {      const againOn = roll(die1)      let rolls = [] @@ -135,7 +122,7 @@ const again = (die1, die2) => {      const rollDie = (die) => {        const roll = die() -      if (roll >= againOn) { +      if (comparison(roll, againOn)) {          rollAgain.push(die)        } @@ -162,49 +149,21 @@ 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) -    } +const againAbove = (die1, die2) => { +  return again(greaterThanOrEqual, die1, die2) +} -    return rolls -  } +const againUnder = (die1, die2) => { +  return again(lessThanOrEqual, die1, die2)  } -const threshold = (die1, die2) => { +const threshold = (comparison, die1, die2) => {    return () => {      const cutoff = roll(die1)      return die2().map(die => {        return () => { -        if (die() >= cutoff) { +        if (comparison(die(), cutoff)) {            return 1          } else {            return 0 @@ -214,20 +173,12 @@ const threshold = (die1, die2) => {    }  } -const thresholdLow = (die1, die2) => { -  return () => { -    const cutoff = roll(die1) +const thresholdHigh = (die1, die2) => { +  return threshold(greaterThanOrEqual, die1, die2) +} -    return die2().map(die => { -      return () => { -        if (die() <= cutoff) { -          return 1 -        } else { -          return 0 -        } -      } -    }) -  } +const thresholdLow = (die1, die2) => { +  return threshold(lessThanOrEqual, die1, die2)  }  exports.pool = pool @@ -239,11 +190,11 @@ exports.subtract = subtract  exports.bonusAdd = bonusAdd  exports.bonusSubtract = bonusSubtract  exports.negative = negative -exports.explode = explode +exports.explodeAbove = explodeAbove  exports.explodeUnder = explodeUnder  exports.keepHigh = keepHigh  exports.keepLow = keepLow -exports.again = again +exports.againAbove = againAbove  exports.againUnder = againUnder -exports.threshold = threshold +exports.thresholdHigh = thresholdHigh  exports.thresholdLow = thresholdLow |