~ubuntu-branches/ubuntu/hardy/dicelab/hardy

« back to all changes in this revision

Viewing changes to README

  • Committer: Bazaar Package Importer
  • Author(s): Robert Lemmen
  • Date: 2007-12-10 17:06:15 UTC
  • Revision ID: james.westby@ubuntu.com-20071210170615-q1av8grz0vjiv397
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
D I C E L A B   R E A D M E
 
2
===========================
 
3
 
 
4
Purpose
 
5
-------
 
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.
 
11
 
 
12
Getting new Versions
 
13
--------------------
 
14
New versions should always be available from 
 
15
http://www.semistable.com/dicelab/
 
16
 
 
17
Build Requirements
 
18
------------------
 
19
In order to build dicelab from source you will need:
 
20
 * GNU Make
 
21
 * gcc
 
22
If you want to hack on this, you will also need:
 
23
 * flex
 
24
 * bison
 
25
 * treecc
 
26
 
 
27
Compilation
 
28
-----------
 
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'.
 
32
 
 
33
Installation
 
34
------------
 
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
 
38
location by hand.
 
39
 
 
40
Win32
 
41
-----
 
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
 
47
LDFLAGS=-L../flex/lib
 
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)
 
50
 
 
51
Running
 
52
-------
 
53
Dicelab is called like this:
 
54
  dicelab [options] [-f <file>]
 
55
The options include
 
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
 
61
                   default is 10000
 
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
 
66
                   when using --calc
 
67
If you don't specify a file with the dice rolling scheme, dicelab will read 
 
68
from stdin.
 
69
 
 
70
Quick Start
 
71
-----------
 
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).
 
80
 
 
81
Full Syntax
 
82
-----------
 
83
<integer> ::= 
 
84
        -?[0-9]+
 
85
<variable> ::=
 
86
        [A-Za-z]+
 
87
<scalar> ::=
 
88
        <integer>
 
89
        | <variable>
 
90
        | ( <scalar> )
 
91
        | - <scalar>
 
92
        | <scalar> + <scalar>
 
93
        | <scalar> - <scalar>
 
94
        | <scalar> * <scalar>
 
95
        | <scalar> / <scalar>
 
96
        | <scalar> % <scalar>
 
97
        | <scalar> ^ <scalar>
 
98
        | <scalar> . <scalar>
 
99
        | d<scalar>
 
100
        | sum <expr>
 
101
        | prod <expr>
 
102
        | count <expr>
 
103
<list> ::=
 
104
        <scalar> # <expr>
 
105
        | ( <list> )
 
106
        | <scalar> .. <scalar>
 
107
        | <expr> , <expr>
 
108
        | perm <expr>
 
109
        | sort <expr>
 
110
        | rev <expr>
 
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>
 
125
<expr> ::=
 
126
        <scalar>
 
127
        <list>
 
128
<input> ::=
 
129
        <expr>
 
130
        | <expr> ; <expr>
 
131
 
 
132
Comments may be inserted by using double slashed (//) as in C.
 
133
 
 
134
Sematics
 
135
--------
 
136
+
 
137
-
 
138
*
 
139
/
 
140
^       
 
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
 
144
-       
 
145
        This is the unary minus operator. Examples: -1
 
146
%       
 
147
        This is the modulus operator. x % y gives the remainder of x divided by y.
 
148
        Examples: 11%2, d6%3
 
149
.       
 
150
        This is the scalar concatenation operator. x . y gives xy, the 
 
151
        concatenation of x and y. Examples: -10.9, d6.d6
 
152
d       
 
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
 
155
sum
 
156
prod
 
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)
 
160
count
 
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)
 
163
#
 
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
 
167
..
 
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
 
171
,
 
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: 
 
174
        1,2 4,(3#d6)
 
175
sort
 
176
    This is the list sorting operator. sort e sorts the list e in ascending
 
177
        order. Examples: sort(10#d6)
 
178
perm
 
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)
 
182
rev
 
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
 
185
        sort(10#d8)
 
186
low
 
187
high
 
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
 
192
first
 
193
last
 
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)
 
198
==
 
199
!=
 
200
<
 
201
>
 
202
<=
 
203
>=
 
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
 
211
drop
 
212
keep
 
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)
 
218
let
 
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
 
224
foreach
 
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
 
228
        x in c do x+1 
 
229
while
 
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)
 
235
if
 
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
 
239
 
 
240
Examples
 
241
--------
 
242
* Count the number of dice greater than 7:
 
243
count >7 5#d10
 
244
 
 
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)
 
247
 
 
248
* Count the number of rolls until a 6 is rolled:
 
249
count (while x=d6 do ((count <6 x)#d6))
 
250
 
 
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)))
 
253
 
 
254
* Roll attributes for a new D&D character:
 
255
6#sum(drop low 1 4#d6)
 
256
 
 
257
* Roll on the 11..66 morale check table in The Gamers' Civil War Brigade 
 
258
Series:
 
259
d6.d6
 
260
 
 
261
* Find the median of 3 d20s:
 
262
high 1 low 2 3#d20
 
263
 
 
264
* 3d6 with rerolls on 6s:
 
265
sum(while x=3#d6 do ((count ==6 x)#d6))
 
266
 
 
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))
 
269
 
 
270
* The Fibonacci sequence is defined by Fn = Fn-1 + Fn-2, with F1 = F2 = 1.
 
271
Calculate the first twenty Fibonacci numbers:
 
272
let n = 20 in
 
273
  let f = (1,1) in
 
274
    foreach i in 1..n do
 
275
      let f = (f,sum(high 2 f)) in
 
276
        if ==n i then f else ()
 
277
 
 
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 
 
282
attacker wins:
 
283
let a = 3#d6 in
 
284
  let b = 2#d6 in
 
285
    count( (<(high 1 a) high 1 b),
 
286
           (<(high 1 low 2 a) low 1 b))
 
287
 
 
288
* Storyteller die roll with target number 8 and botches indicated at -1:
 
289
let c=5#d10 in
 
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
 
294
 
 
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:
 
303
let x = 2#d8,d10 in
 
304
  (count >15 sum x)#
 
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
 
312
 
 
313
 
 
314
Credits
 
315
-------
 
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.
 
319
 
 
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.
 
323
 
 
324
This code was written by Robert Lemmen <robertle@semistable.com>, who would be
 
325
glad to hear your questions and remarks.