m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--__tests__/dice.test.js41
-rw-r--r--__tests__/lexer.test.js12
-rw-r--r--__tests__/parser.test.js12
-rw-r--r--index.js2
-rw-r--r--src/dice.js9
-rw-r--r--src/lexer.js1
-rw-r--r--src/parser.js1
7 files changed, 78 insertions, 0 deletions
diff --git a/__tests__/dice.test.js b/__tests__/dice.test.js
index 375c9ad..9c03a48 100644
--- a/__tests__/dice.test.js
+++ b/__tests__/dice.test.js
@@ -9,6 +9,7 @@ const {
bonusAdd,
bonusSubtract,
bonusMultiply,
+ bonusDivide,
negative,
explodeAbove,
explodeUnder,
@@ -503,6 +504,46 @@ describe('bonusMultiply', () => {
})
})
+describe('bonusDivide', () => {
+ describe('1d20/3', () => {
+ const die = bonusDivide(d(constant(1), constant(20)), constant(3))
+ testDie(die, {
+ diceCount: 1,
+ average: {
+ average: 3.15
+ },
+ variance: {
+ variance: 3.73
+ },
+ bounds: {
+ low: 0,
+ high: 6,
+ expectLow: true,
+ expectHigh: true
+ }
+ })
+ })
+
+ describe('3d4/2', () => {
+ const die = bonusDivide(d(constant(3), constant(4)), constant(2))
+ testDie(die, {
+ diceCount: 3,
+ average: {
+ average: 3
+ },
+ variance: {
+ variance: 1.5
+ },
+ bounds: {
+ low: 0,
+ high: 6,
+ expectLow: true,
+ expectHigh: true
+ }
+ })
+ })
+})
+
describe('negative', () => {
describeBasicDie(1, 6, defaultNumberRolls, true)
describeBasicDie(0, 6, defaultNumberRolls, true)
diff --git a/__tests__/lexer.test.js b/__tests__/lexer.test.js
index 31150bc..7124746 100644
--- a/__tests__/lexer.test.js
+++ b/__tests__/lexer.test.js
@@ -253,6 +253,18 @@ describe('lex', () => {
})
})
+ describe('bonusDivide', () => {
+ test('3d4/1', () => {
+ expect(lex('3d4/1')).toEqual([
+ { type: 'constant', value: 3 },
+ { type: 'd' },
+ { type: 'constant', value: 4 },
+ { type: 'divide' },
+ { type: 'constant', value: 1 }
+ ])
+ })
+ })
+
describe('again', () => {
test('6A3d6', () => {
expect(lex('6A3d6')).toEqual([
diff --git a/__tests__/parser.test.js b/__tests__/parser.test.js
index 5580b4c..3c9f6ec 100644
--- a/__tests__/parser.test.js
+++ b/__tests__/parser.test.js
@@ -165,6 +165,18 @@ describe('parse', () => {
})
})
+ it('parses divisional bonuses', () => {
+ expect(parse('3d4/1')).toEqual({
+ type: 'bonusDivide',
+ left: {
+ type: 'd',
+ left: { type: 'constant', value: 3 },
+ right: { type: 'constant', value: 4 }
+ },
+ right: { type: 'constant', value: 1 }
+ })
+ })
+
test('bonus binds stronger than addition', () => {
expect(parse('2d6 + 2d6+2d6')).toEqual({
type: 'add',
diff --git a/index.js b/index.js
index 4a0d942..13e6378 100644
--- a/index.js
+++ b/index.js
@@ -39,6 +39,8 @@ const interpret = tree => {
return D.bonusSubtract(interpret(tree.left), interpret(tree.right))
case 'bonusMultiply':
return D.bonusMultiply(interpret(tree.left), interpret(tree.right))
+ case 'bonusDivide':
+ return D.bonusDivide(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 6351929..0197f25 100644
--- a/src/dice.js
+++ b/src/dice.js
@@ -81,6 +81,14 @@ const bonusMultiply = (die1, die2) => {
}
}
+const bonusDivide = (die1, die2) => {
+ return () => {
+ return die1().map(die => {
+ return () => Math.floor(die() / roll(die2))
+ })
+ }
+}
+
const explode = (comparison, die1, die2) => {
return () => {
const explodeOn = roll(die1)
@@ -225,6 +233,7 @@ exports.divide = divide
exports.bonusAdd = bonusAdd
exports.bonusSubtract = bonusSubtract
exports.bonusMultiply = bonusMultiply
+exports.bonusDivide = bonusDivide
exports.negative = negative
exports.explodeAbove = explodeAbove
exports.explodeUnder = explodeUnder
diff --git a/src/lexer.js b/src/lexer.js
index e700f87..6b75129 100644
--- a/src/lexer.js
+++ b/src/lexer.js
@@ -23,6 +23,7 @@ newLexemeType('bigDivide', ' / ')
newLexemeType('plus', '\\+')
newLexemeType('minus', '-')
newLexemeType('times', '\\*')
+newLexemeType('divide', '/')
newLexemeType('(', '\\(')
newLexemeType(')', '\\)')
newLexemeType('E', 'E')
diff --git a/src/parser.js b/src/parser.js
index 54dc0ae..acae9ad 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -76,6 +76,7 @@ newInfix('bigDivide', 23, { type: 'divide' })
newInfix('plus', 25, { type: 'bonusAdd' })
newInfix('minus', 25, { type: 'bonusSubtract' })
newInfix('times', 26, { type: 'bonusMultiply' })
+newInfix('divide', 26, { type: 'bonusDivide' })
newSymbol('minus', (parser) => {
return {
type: 'negative',