1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

# dicebag
A dice expression parser and roller.
## Installation
# in a local node_modules/
npm install save dicebag
# globally, to use the CLI
npm install g dicebag
## Commandline usage
dicebag [p] [<dice expression>]
If a dice expression is provided, prints the result of rolling those dice and
exits. Otherwise, reads expressions from `stdin` in a loop.
* `p` print dice pools (default behavior is to print the dice's sum)
### Examples
$ dicebag 1d6
1
$ dicebag "2d8 + 1d4"
7
$ dicebag p "2d8 + 1d4"
[ 5, 3, 4 ]
## Library usage
const { parse, pool, roll } = require('dicebag')
The API consists of three functions:
* `parse(diceExpression)` parses an expression into an object understood by the
other two functions.
* `pool(dice)` rolls the dice and returns an array of their results.
* `roll(dice)` rolls the dice and returns their sum.
### Examples
const d6 = parse('1d6')
roll(d6) // 4
roll(d6) // 5
pool(d6) // [ 2 ]
const dice = parse('2d6 + 1d8')
roll(dice) // 10
pool(dice) // [ 1, 4, 7 ]
## Dice expressions
### Basics
Simple expressions involving standard dice notation as used in most roleplaying
games are supported. You can do things like:
* `XdY`: rolls `X` `Y`sided dice (`1d6` is a single 6sided die, `2d4` is two
4sided dice).
* `dX` is the same as `1dX` (so you can shorten `1d6` to `d6`).
* `dice +/ constant`: rolls the dice, adds/subtracts the constant.
* `dice +/ moreDice`: sums/takes the difference of the results of rolling
`dice` and `moreDice`.
* `number K dice`: rolls the dice and keeps the `number` highest results. For
example, `1K2d20` is the "rolling with advantage" mechanic from 5th Edition
Dungeons and Dragons (roll two d20's, keep the highest).
* `number k dice`: like `K` but keeps the `number` lowest results. `1k2d20` is
D&D5E's "disadvantage" mechanic.
### Full syntax and semantics
**Note:** this is still an early version. Syntax and semantics will be expanded
in future versions. *Backwards incompatible changes are possible.*
The parser recognizes the following grammar:
Die ::= <an integer>
 '(' Die ')'
 Die 'd' Die
 'd' Die
 Die ' + ' Die
 Die '  ' Die
 Die ' * ' Die
 Die ' / ' Die
 Die '+' Die
 Die '' Die
 Die '*' Die
 Die '/' Die
 '' Die
 Die 'E' Die
 Die 'e' Die
 Die 'K' Die
 Die 'k' Die
 Die 'A' Die
 Die 'a' Die
 Die 'T' Die
 Die 't' Die
 Die ' x ' Die
Semantics are defined in terms of the `pool` function.
* `N`, where `N` is an integer, is a die that always rolls a single value
equal to `N`. `pool` returns an array containing just `N`.
* `DdE`, where `D` and `E` are dice expressions, is a die that rolls a number of
dice equal to the result of rolling `D`, where each die has a number of sides
equal to the result of rolling `E`. `pool` returns an array of `roll(D)`
numbers, each between 1 and `roll(E)`. *Note:* if `D` or `E` evaluates to a
negative number, the behavior is undefined.
* `dD` is equivalent to `1dD`.
* `D + E` appends the dice pool generated by `E` to the dice pool generated by
`D`.
* `D` returns the opposites of values generated by `D`.
* `D  E` is equivalent to `D + (E)`.
* `D * E` generates a dicepool with a single value  the product of `roll(D)`
and `roll(E)`.
* `D / E` generates a dicepool with a single value  the result of integer
division of `roll(D)` by `roll(E)`.
* `D+E` is the additive bonus operation. For each die in `D`'s pool, the die is
rolled and `roll(E)` is added to its result.
* `DE` is equivalent to `D+(E)`.
* `D*E` is like `D+E` but multiplies each die in `D`'s pool the result of
rolling `E`.
* `D/E` is like `D+E` but performs integer division on each die in `D`'s pool
by the result of rolling `E`.
* `DEF` (here `E` is the literal symbol `E`, `D` and `F` are dice expressions)
is an "exploding die." First `D` is rolled. Now each die in the dice pool
generated by `F` is rolled repeatedly until it rolls something less than the
value rolled on `D`. The die's result is the sum of all those rolls. *Note:*
this could lead to an infinite evaluation if `F` always rolls higher than a
possible result of `D`.
* `DeF` is like `E`, but explodes on values *less* than what was rolled on `D`.
* `DKE` is the "keep highest" mechanic. First `D` is rolled. Now each die in the
dice pool generated by `E` is rolled, and the resulting dice pool is composed
of those dice that rolled highest, taking up to as many dice as the result of
rolling `D`.
* `DkE` is the "keep lowest" mechanic. Like `K`, but selects the lowest rolling
dice.
* `DAE` might roll some of the dice in `E`'s pool again. First `D` is rolled.
Now each die in the dice pool generated by `E` is rolled repeatedly until it
rolls something less than the value rolled on `D`. Each such roll is treated
as a separate die, the results for each die are not accumulated like with
exploding die. *Note:* this could lead to an infinite evaluation if `E` always
rolls higher than a possible result of `D`.
* `DaE` is like `A`, but rolls again on values *less* than what was rolled on
`D`.
* `DTE` applies a threshold to the dice in `E`'s pool. First `D` is rolled. Now
when a die from `E`'s pool rolls below the value rolled on `D`, its value is
0, otherwise its value is 1.
* `DtE` is like `T` but dice with values *higher* than what was rolled on `D` are
counted as 0's, the rest as 1's.
* `D x E` will repeatedly roll `D`. First `E` is rolled, then `D` is rolled as
many times as the value rolled on `E`. The pools generated by `D` are
concatenated to generate the new pool. *Note:* if `E` evaluates to a
negative number, the behavior is undefined.
Additionally:
* The binary arithmetic operations (` + `, `  `, ` * `, ` / `) are left
associative.
* The binary arithmetic operations bind as expected (multiplication and division
bind stronger than addition and subtraction).
* The bonus operations (`+`, ``, `*`, `/`) are left associative. They bind
stronger than arithmetic operations. `/` and `*` bind stronger than `+` and
``.
* The die operations (`d`, `E`, `K`, etc.) are right associative (`1d2d3` is
equivalent to `1d(2d3)`, use explicit parentheses if you need `(1d2)d3`).
* Die operations bind stronger than the binary arithmetic operations
(`1d6 + 1d4` is equivalent to `(1d6) + (1d4)`) and the bonus operations.
* The repetition operation ` x ` is left assosiative. It binds stronger than
the standard arithmetic operations, but weaker than the dice operations and
the bonus operations.
