m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2017-08-30 16:30:23 -0400
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2017-08-30 16:30:23 -0400
commit5b77a409c912f7251da8c170bd4a3aa8826d989b (patch)
tree0b3131a6a1c87b7a3af3537d4d548392866bb812
parent7efea0582dda35cd7dc0c370ef3b56c84b2f2291 (diff)
Implement again under
-rw-r--r--__tests__/dice.test.js24
-rw-r--r--__tests__/lexer.test.js10
-rw-r--r--__tests__/parser.test.js10
-rw-r--r--index.js2
-rw-r--r--src/dice.js37
-rw-r--r--src/lexer.js1
-rw-r--r--src/parser.js1
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', () => {
diff --git a/index.js b/index.js
index 8c52ad1..740b96e 100644
--- a/index.js
+++ b/index.js
@@ -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' })