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 6a9ba46..375c9ad 100644
--- a/__tests__/dice.test.js
+++ b/__tests__/dice.test.js
@@ -8,6 +8,7 @@ const {
divide,
bonusAdd,
bonusSubtract,
+ bonusMultiply,
negative,
explodeAbove,
explodeUnder,
@@ -462,6 +463,46 @@ describe('bonusSubtract', () => {
})
})
+describe('bonusMultiply', () => {
+ describe('1d20*3', () => {
+ const die = bonusMultiply(d(constant(1), constant(20)), constant(3))
+ testDie(die, {
+ diceCount: 1,
+ average: {
+ average: 31.5
+ },
+ variance: {
+ variance: 299.25
+ },
+ bounds: {
+ low: 3,
+ high: 60,
+ expectLow: true,
+ expectHigh: true
+ }
+ })
+ })
+
+ describe('3d4*2', () => {
+ const die = bonusMultiply(d(constant(3), constant(4)), constant(2))
+ testDie(die, {
+ diceCount: 3,
+ average: {
+ average: 15
+ },
+ variance: {
+ variance: 15
+ },
+ bounds: {
+ low: 6,
+ high: 24,
+ 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 6745715..31150bc 100644
--- a/__tests__/lexer.test.js
+++ b/__tests__/lexer.test.js
@@ -241,6 +241,18 @@ describe('lex', () => {
})
})
+ describe('bonusMultiply', () => {
+ test('3d4*1', () => {
+ expect(lex('3d4*1')).toEqual([
+ { type: 'constant', value: 3 },
+ { type: 'd' },
+ { type: 'constant', value: 4 },
+ { type: 'times' },
+ { 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 d696b3e..5580b4c 100644
--- a/__tests__/parser.test.js
+++ b/__tests__/parser.test.js
@@ -153,6 +153,18 @@ describe('parse', () => {
})
})
+ it('parses multiplicative bonuses', () => {
+ expect(parse('3d4*1')).toEqual({
+ type: 'bonusMultiply',
+ 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 cc768cb..4a0d942 100644
--- a/index.js
+++ b/index.js
@@ -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 'bonusMultiply':
+ return D.bonusMultiply(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 5a484b0..6351929 100644
--- a/src/dice.js
+++ b/src/dice.js
@@ -73,6 +73,14 @@ const bonusSubtract = (die1, die2) => {
}
}
+const bonusMultiply = (die1, die2) => {
+ return () => {
+ return die1().map(die => {
+ return () => die() * roll(die2)
+ })
+ }
+}
+
const explode = (comparison, die1, die2) => {
return () => {
const explodeOn = roll(die1)
@@ -216,6 +224,7 @@ exports.multiply = multiply
exports.divide = divide
exports.bonusAdd = bonusAdd
exports.bonusSubtract = bonusSubtract
+exports.bonusMultiply = bonusMultiply
exports.negative = negative
exports.explodeAbove = explodeAbove
exports.explodeUnder = explodeUnder
diff --git a/src/lexer.js b/src/lexer.js
index 248a9b2..e700f87 100644
--- a/src/lexer.js
+++ b/src/lexer.js
@@ -22,6 +22,7 @@ newLexemeType('bigTimes', ' \\* ')
newLexemeType('bigDivide', ' / ')
newLexemeType('plus', '\\+')
newLexemeType('minus', '-')
+newLexemeType('times', '\\*')
newLexemeType('(', '\\(')
newLexemeType(')', '\\)')
newLexemeType('E', 'E')
diff --git a/src/parser.js b/src/parser.js
index b1f6ebb..54dc0ae 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -75,6 +75,7 @@ newInfix('bigTimes', 23, { type: 'multiply' })
newInfix('bigDivide', 23, { type: 'divide' })
newInfix('plus', 25, { type: 'bonusAdd' })
newInfix('minus', 25, { type: 'bonusSubtract' })
+newInfix('times', 26, { type: 'bonusMultiply' })
newSymbol('minus', (parser) => {
return {
type: 'negative',