1
D I C E L A B R E A D M E
2
===========================
6
Dicelab is intended to examine dice rolling schemes and roll dice according
7
to such a scheme. It may be helpfull when designing or playing certain games.
8
The current version can determine the statistical distribution by rolling over
9
and over again, or by actually doing the maths. The latter is more precise, but
10
might be prohibitively slow in some cases.
14
New versions should always be available from
15
http://www.semistable.com/dicelab/
19
In order to build dicelab from source you will need:
22
If you want to hack on this, you will also need:
29
To build this program run './configure' and inspect the output for problems.
30
This will also honour the '--prefix' option to specify where you want the
31
program to be installed. To build dicelab then run 'make'.
35
The command 'make install' (as root) will install the program and accompanying
36
documentation files to the location specified during './configure' (the default
37
is /usr). Optionally, you can of course copy the files to their intended
42
Dicelab can be built into a Win32 (commandline) executable using Mingw32 (and
43
probably other tools as well). In order to do this, you need a static flex
44
library for the target system, and then set CC and LDFLAGS accordingly. In my
45
case i do change the Makefile that gets generated by ./configure:
46
CC=i586-mingw32msvc-cc
48
Should you have problems getting this to work, you can always mail me and i'll
49
provide you with a binary (though i don't understand why you use win32 at all)
53
Dicelab is called like this:
54
dicelab [options] [-f <file>]
56
--help -h -? print a help message
57
--version -v display the version number
58
--print-tree -p print the parse tree (for debugging purposes)
59
--eval -e evaluate the statistical distribution by re-rollingp
60
--count -c specify the number of rolls used with --eval
62
--roll -r roll the dice as specified. This will also be used
63
if no other action is requested
64
--threshold -t cutoff threshold, results with a probability less
65
than this value will be discarded by some operations
67
If you don't specify a file with the dice rolling scheme, dicelab will read
72
Single die rolls may be made using the 'd' operator, followed by the number of
73
faces on the die to be rolled. E.g., d6 will roll a single six-sided die, and
74
d2 will flip a coin. Expressions may be modified by the standard arithmetic
75
operators. d10-1 will yield a value between 0 and 9, inclusive. In order to
76
roll multiple dice of the same type, use the repetition operator '#'. 2#d6
77
will roll two six-sided dice; this is not the same as 2*d6, which rolls only
78
a single die but multipies the result by two, or 2d6 which will cause a syntax
79
error. In order to get the sum of two six-sided dice, do sum(2#d6).
106
| <scalar> .. <scalar>
111
| (drop|keep)? low <scalar> <expr>
112
| (drop|keep)? high <scalar> <expr>
113
| (drop|keep)? first <scalar> <expr>
114
| (drop|keep)? last <scalar> <expr>
115
| (drop|keep)? == <scalar> <expr>
116
| (drop|keep)? != <scalar> <expr>
117
| (drop|keep)? < <scalar> <expr>
118
| (drop|keep)? > <scalar> <expr>
119
| (drop|keep)? <= <scalar> <expr>
120
| (drop|keep)? >= <scalar> <expr>
121
| if <expr> then <expr> else <expr>
122
| let <variable> = <expr> in <expr>
123
| while <variable> = <expr> do <expr>
124
| foreach <variable> in <expr> do <expr>
132
Comments may be inserted by using double slashed (//) as in C.
141
These are the familiar binary arithmetic operators for addition,
142
subtraction, multiplication, division, and exponentiation. Division
143
rounds toward zero. Examples: 5+7, d6-1, 2^10
145
This is the unary minus operator. Examples: -1
147
This is the modulus operator. x % y gives the remainder of x divided by y.
150
This is the scalar concatenation operator. x . y gives xy, the
151
concatenation of x and y. Examples: -10.9, d6.d6
153
This is the die roll operator. dn gives the value of a single roll of an
154
n-sided die. Examples: d6, 2#d6
157
These are the extended sum and product operators. If e is an expression,
158
sum e and prod e give the sum of the members of e and the product of the
159
members of e, respectively. Examples: sum(1..100), prod(3#d6)
161
This is the list size operator. If e is an expression, then count e gives
162
the number of members of e. Examples: count(1,2,3), count(== 6 10#d6)
164
This is the list repetition operator. If n is a nonnegative scalar and e is
165
an expression, then n#e is a list containing the results of n evaluations
166
of e. Examples: 10#8, 3#d10
168
This is the range operator. If x and y are scalars, then x..y is a list
169
consisting of the interval [x,y]. If x>y, then the resulting list is empty.
170
Examples: 1..10, 4..d10
172
This is the list concatenation operator. v,u gives the list consisting of
173
all of the members of v, followed by all of the members of u. Examples:
176
This is the list sorting operator. sort e sorts the list e in ascending
177
order. Examples: sort(10#d6)
179
This is the list permutation operator. sort e results in a random
180
permutation of the list e. Use perm to shuffle a list.
181
Examples: perm(1..52)
183
This is the list reversal operator. rev e results in a list with the same
184
members as the list e, but in reverse order. Examples: rev(1..10), rev
188
These operators act as filters by finding the least and greatest values in
189
lists. If n is a nonnegative scalar and e is an expression, then low n e
190
gives the n least members of e, and high n e gives the n greatest members
191
of e. Examples: high 3 5#d6
194
These operators act as filters by finding initial and final segments of
195
lists. If n is a nonnegtive scalar and e is an expression, then first n e
196
gives the first n members of e, and last n e gives the last n members of e.
197
Examples: first 3 (1..10)
204
These operators act as filters by finding values in lists which meet given
205
conditions. If x is a scalar and e is an expression, then == x e gives the
206
list of members of e equal to x; != x e gives the list of members of e not
207
equal to x; < x e gives the list of members of e less than x; > x e gives
208
the list of members of e greater than x; <= x e gives the list of members
209
of e less than or equal to x; >= x e gives the list of members of e greater
210
than or equal to x. Examples: >= 3 5#d6
213
These operators modify filters on lists. If fop is a filter operation on an
214
expression e, then keep fop e has the same result as fop e and drop fop e
215
evaluates to e less keep fop e. In other words, drop negates filter
216
conditions, and keep affirms them. keep is never necessary and exists only
217
for symmetry. Examples: sum(drop low 1 4#d6)
219
This is the variable assignment and substitution operator. If x is a
220
variable and e and f are an expressions, then let x = e in f gives the list
221
which results from evaluating f with the value of e substituted for every
222
occurance of x in f. Evaluation of e is done prior to substitution.
223
Examples: let x = d6 in x*x
225
This is the bounded iteration operator. If x is a variable and e and f are
226
expressions, then foreach x in e do f gives the list which results from
227
assigning to x each of the members of e and evaluating f. Examples: foreach
230
This is the unbounded iteration operator. If x is a variable and e and f
231
are expressions, then while x = e do f is the list v0,v1,...,vn, where v0
232
is the result of evaluating e and vi+1 is the result of assigning vi to x
233
and evaluating f, stopping at the first vi which is empty.
234
Examples: while x=d6 do ((count <6 x)#d6)
236
This is the branching operator. If e, f, and g are expressions, then if e
237
then f else g gives f if e is nonempty, and g otherwise. Examples: if
238
count(>4 2#d6) then 1 else 0
242
* Count the number of dice greater than 7:
245
* Count the number of dice greater than 7 minus the number of dice equal to 1:
246
let c=5#d10 in (count >7 c)-(count ==1 c)
248
* Count the number of rolls until a 6 is rolled:
249
count (while x=d6 do ((count <6 x)#d6))
251
* Count the number of rolls until a 6 is rolled, more efficiently:
252
count (while x=(d6/6) do ((count <1 x)#(d6/6)))
254
* Roll attributes for a new D&D character:
255
6#sum(drop low 1 4#d6)
257
* Roll on the 11..66 morale check table in The Gamers' Civil War Brigade
261
* Find the median of 3 d20s:
264
* 3d6 with rerolls on 6s:
265
sum(while x=3#d6 do ((count ==6 x)#d6))
267
* Roll 7 d10 and find the largest sum of identical dice:
268
let x = 7#d10 in high 1 (foreach y in 1..10 do sum (==y x))
270
* The Fibonacci sequence is defined by Fn = Fn-1 + Fn-2, with F1 = F2 = 1.
271
Calculate the first twenty Fibonacci numbers:
275
let f = (f,sum(high 2 f)) in
276
if ==n i then f else ()
278
* Risk has battles where the attacker rolls 3d6 and the defender rolls 2d6.
279
The highest attacker die is matched with the highest defender die and the
280
second highest attacker die to the second highest defender die. For both
281
matches, the highest wins, with ties going to the defender. The number of
285
count( (<(high 1 a) high 1 b),
286
(<(high 1 low 2 a) low 1 b))
288
* Storyteller die roll with target number 8 and botches indicated at -1:
290
let succs = count >7 c in
291
let ones = count ==1 c in
292
if >0 succs then high 1 (0,succs-ones)
293
else if >0 ones then -1 else 0
295
* Combat in Silent Death is rather complex. Three dice are rolled. If their
296
sum is above a target, the roll is a hit. To calculate damage, the same dice
297
are sorted. If all three are equal, all are summed to yield the damage. If
298
the least two are equal, but the third is higher, the high die is the damage.
299
If the two highest are equal, but the third is lower, the two high dice are
300
summed to yield the damage. If all three dice are different, the middle die
301
is the damage. This example assumes that the dice are two d8s and a d10, with
302
a target number of 15:
305
let a = low 1 x in // low die
306
let b = high 1 low 2 x in // middle die
307
let c = high 1 x in // high die
308
if ==a ==b c then a+b+c // all equal
309
else if ==a <c b then c // two low equal
310
else if >a ==c b then b+c // two high equal
311
else b // all different
316
Dicelab is based on the excellent work "roll" by Torben Mogensen
317
(http://www.diku.dk/~torbenm/Dice.zip). Without his work and comments, this
318
would hardly ever have happened.
320
The current language specification and the extensions to the original language
321
are derived from the work of Joel Uckelman (http://dice.nomic.net/bones.html),
322
most of the documentation is stolen from him as well.
324
This code was written by Robert Lemmen <robertle@semistable.com>, who would be
325
glad to hear your questions and remarks.