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

« back to all changes in this revision

Viewing changes to dicelab.1

  • 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
.TH dicelab 1 "February 2007" "dicelab v0.2" "Dicelab - examine and roll dice"
 
2
.SH NAME
 
3
dicelab \- roll and examine dice rolling schemes
 
4
.SH SYNOPSIS
 
5
.B dicelab
 
6
.I [options]
 
7
.I [-f <file>]
 
8
 
 
9
.SH OPTIONS
 
10
.TP
 
11
.BR \-h ", "\-\-help ", "\-? 
 
12
print a help message
 
13
.TP
 
14
.BR \-\-version ", "\-v
 
15
display version number
 
16
.TP
 
17
.BR \-\-print\-tree ", "\-p
 
18
print the parse tree (for debugging purposes)
 
19
.TP
 
20
.BR \-\-roll ", "\-r
 
21
roll the dice as specified. This will also be used if no other action is
 
22
requested
 
23
.TP
 
24
.BR \-\-eval ", "\-e
 
25
reroll many times and sum up the results to get a statistical distribution of
 
26
values
 
27
.TP
 
28
.BR \-\-count ", "\-c
 
29
specify the number of rerolls for --eval, default it 10000
 
30
.TP
 
31
.BR \-f <file>
 
32
read the scheme description from file instead from stdin
 
33
 
 
34
.SH DESCRIPTION
 
35
Dicelab reads a description of a dice rolling scheme from a file or from stdin
 
36
if no file is specified and then rolls or examines this scheme.
 
37
 
 
38
.SH QUICK START
 
39
Single die rolls may be made using the 'd' operator, followed by the number of
 
40
faces on the die to be rolled. E.g., d6 will roll a single six-sided die, and 
 
41
d2 will flip a coin. Expressions may be modified by the standard arithmetic
 
42
operators. d10-1 will yield a value between 0 and 9, inclusive. In order to 
 
43
roll multiple dice of the same type, use the repetition operator '#'. 2#d6 
 
44
will roll two six-sided dice; this is not the same as 2*d6, which rolls only 
 
45
a single die but multipies the result by two, or 2d6 which will cause a syntax
 
46
error. In order to get the sum of two six-sided dice, do sum(2#d6).
 
47
 
 
48
.SH FULL SYNTAX
 
49
.NF
 
50
 <integer> ::= 
 
51
     -?[0-9]+
 
52
 <variable> ::=
 
53
     [A-Za-z]+
 
54
 <scalar> ::=
 
55
     <integer>
 
56
     | <variable>
 
57
     | ( <scalar> )
 
58
     | - <scalar>
 
59
     | <scalar> + <scalar>
 
60
     | <scalar> - <scalar>
 
61
     | <scalar> * <scalar>
 
62
     | <scalar> / <scalar>
 
63
     | <scalar> % <scalar>
 
64
     | <scalar> ^ <scalar>
 
65
     | <scalar> . <scalar>
 
66
     | d<scalar>
 
67
     | sum <expr>
 
68
     | prod <expr>
 
69
     | count <expr>
 
70
 <list> ::=
 
71
     <scalar> # <expr>
 
72
     | ( <list> )
 
73
     | <scalar> .. <scalar>
 
74
     | <expr> , <expr>
 
75
     | perm <expr>
 
76
     | sort <expr>
 
77
     | rev <expr>
 
78
     | (drop|keep)? low <scalar> <expr>
 
79
     | (drop|keep)? high <scalar> <expr>
 
80
     | (drop|keep)? first <scalar> <expr>
 
81
     | (drop|keep)? last <scalar> <expr>
 
82
     | (drop|keep)? == <scalar> <expr>
 
83
     | (drop|keep)? != <scalar> <expr>
 
84
     | (drop|keep)? < <scalar> <expr>
 
85
     | (drop|keep)? > <scalar> <expr>
 
86
     | (drop|keep)? <= <scalar> <expr>
 
87
     | (drop|keep)? >= <scalar> <expr>
 
88
     | if <expr> then <expr> else <expr>
 
89
     | let <variable> = <expr> in <expr>
 
90
     | while <variable> = <expr> do <expr>
 
91
     | foreach <variable> in <expr> do <expr>
 
92
 <expr> ::=
 
93
     <scalar>
 
94
     <list>
 
95
 <input> ::=
 
96
     <expr>
 
97
     | <expr> ; <expr>
 
98
.FI
 
99
 
 
100
Comments may be inserted by using double slashed (//) as in C.
 
101
 
 
102
.SH SEMANTICS
 
103
.BR + " "- " "* " "/ " "^
 
104
.IP     
 
105
These are the familiar binary arithmetic operators for addition,
 
106
subtraction, multiplication, division, and exponentiation. Division 
 
107
rounds toward zero. Examples: 5+7, d6-1, 2^10
 
108
.PP
 
109
.BR -
 
110
.IP
 
111
This is the unary minus operator. Examples: -1
 
112
.PP     
 
113
.BR %   
 
114
.IP
 
115
This is the modulus operator. x % y gives the remainder of x divided by y.
 
116
Examples: 11%2, d6%3
 
117
.PP
 
118
.BR .   
 
119
.IP
 
120
This is the scalar concatenation operator. x . y gives xy, the 
 
121
concatenation of x and y. Examples: -10.9, d6.d6
 
122
.PP
 
123
.BR d   
 
124
.IP
 
125
This is the die roll operator. dn gives the value of a single roll of an
 
126
n-sided die. Examples: d6, 2#d6
 
127
.PP 
 
128
.BR sum " "prod
 
129
.IP
 
130
These are the extended sum and product operators. If e is an expression, 
 
131
sum e and prod e give the sum of the members of e and the product of the 
 
132
members of e, respectively. Examples: sum(1..100), prod(3#d6)
 
133
.PP
 
134
.BR count
 
135
.IP
 
136
This is the list size operator. If e is an expression, then count e gives
 
137
the number of members of e. Examples: count(1,2,3), count(== 6 10#d6)
 
138
.PP
 
139
.BR #
 
140
.IP
 
141
This is the list repetition operator. If n is a nonnegative scalar and e is
 
142
an expression, then n#e is a list containing the results of n evaluations 
 
143
of e. Examples: 10#8, 3#d10
 
144
.PP
 
145
.BR ..
 
146
.IP
 
147
This is the range operator. If x and y are scalars, then x..y is a list
 
148
consisting of the interval [x,y]. If x>y, then the resulting list is empty.
 
149
Examples: 1..10, 4..d10
 
150
.PP
 
151
.BR ,
 
152
.IP
 
153
This is the list concatenation operator. v,u gives the list consisting of
 
154
all of the members of v, followed by all of the members of u. Examples: 
 
155
1,2 4,(3#d6)
 
156
.PP
 
157
.BR sort
 
158
.IP
 
159
This is the list sorting operator. sort e sorts the list e in ascending
 
160
order. Examples: sort(10#d6)
 
161
.PP
 
162
.BR perm
 
163
.IP
 
164
This is the list permutation operator. sort e results in a random
 
165
permutation of the list e. Use perm to shuffle a list. 
 
166
Examples: perm(1..52)
 
167
.PP 
 
168
.BR rev
 
169
.IP
 
170
This is the list reversal operator. rev e results in a list with the same
 
171
members as the list e, but in reverse order. Examples: rev(1..10), rev
 
172
sort(10#d8)
 
173
.PP 
 
174
.BR low " "high
 
175
.IP
 
176
These operators act as filters by finding the least and greatest values in
 
177
lists. If n is a nonnegative scalar and e is an expression, then low n e
 
178
gives the n least members of e, and high n e gives the n greatest members 
 
179
of e. Examples: high 3 5#d6
 
180
.PP
 
181
.BR first " "last
 
182
.IP
 
183
These operators act as filters by finding initial and final segments of
 
184
lists. If n is a nonnegtive scalar and e is an expression, then first n e
 
185
gives the first n members of e, and last n e gives the last n members of e.
 
186
Examples: first 3 (1..10)
 
187
.PP
 
188
.BR == " "!= " "< " "> " "<= " ">=
 
189
.IP
 
190
These operators act as filters by finding values in lists which meet given
 
191
conditions. If x is a scalar and e is an expression, then == x e gives the
 
192
list of members of e equal to x; != x e gives the list of members of e not
 
193
equal to x; < x e gives the list of members of e less than x; > x e gives
 
194
the list of members of e greater than x; <= x e gives the list of members 
 
195
of e less than or equal to x; >= x e gives the list of members of e greater
 
196
than or equal to x. Examples: >= 3 5#d6
 
197
.PP
 
198
.BR drop " "keep
 
199
.IP
 
200
These operators modify filters on lists. If fop is a filter operation on an
 
201
expression e, then keep fop e has the same result as fop e and drop fop e
 
202
evaluates to e less keep fop e. In other words, drop negates filter
 
203
conditions, and keep affirms them. keep is never necessary and exists only
 
204
for symmetry. Examples: sum(drop low 1 4#d6)
 
205
.PP
 
206
.BR let
 
207
.IP
 
208
This is the variable assignment and substitution operator. If x is a
 
209
variable and e and f are an expressions, then let x = e in f gives the list
 
210
which results from evaluating f with the value of e substituted for every
 
211
occurance of x in f. Evaluation of e is done prior to substitution.
 
212
Examples: let x = d6 in x*x
 
213
.PP
 
214
.BR foreach
 
215
.IP
 
216
This is the bounded iteration operator. If x is a variable and e and f are
 
217
expressions, then foreach x in e do f gives the list which results from
 
218
assigning to x each of the members of e and evaluating f. Examples: foreach
 
219
x in c do x+1 
 
220
.PP
 
221
.BR while
 
222
.IP
 
223
This is the unbounded iteration operator. If x is a variable and e and f 
 
224
are expressions, then while x = e do f is the list v0,v1,...,vn, where v0 
 
225
is the result of evaluating e and vi+1 is the result of assigning vi to x 
 
226
and evaluating f, stopping at the first vi which is empty. 
 
227
Examples: while x=d6 do ((count <6 x)#d6)
 
228
.PP
 
229
.BR if
 
230
.IP
 
231
This is the branching operator. If e, f, and g are expressions, then if e
 
232
then f else g gives f if e is nonempty, and g otherwise. Examples: if
 
233
count(>4 2#d6) then 1 else 0
 
234
 
 
235
.SH EXAMPLES
 
236
Count the number of dice greater than 7:
 
237
.IP
 
238
.NF
 
239
count >7 5#d10
 
240
.FI
 
241
 
 
242
.PP
 
243
Count the number of dice greater than 7 minus the number of dice equal to 1:
 
244
.IP
 
245
.NF
 
246
let c=5#d10 in (count >7 c)-(count ==1 c)
 
247
.FI
 
248
 
 
249
.PP
 
250
Count the number of rolls until a 6 is rolled:
 
251
.IP
 
252
.NF
 
253
count (while x=d6 do ((count <6 x)#d6))
 
254
.FI
 
255
 
 
256
.PP
 
257
Count the number of rolls until a 6 is rolled, more efficiently:
 
258
.IP
 
259
.NF
 
260
count (while x=(d6/6) do ((count <1 x)#(d6/6)))
 
261
.FI
 
262
 
 
263
.PP
 
264
Roll attributes for a new D&D character:
 
265
.IP
 
266
.NF
 
267
6#sum(drop low 1 4#d6)
 
268
.FI
 
269
 
 
270
.PP
 
271
Roll on the 11..66 morale check table in The Gamers' Civil War Brigade 
 
272
Series:
 
273
.IP
 
274
.NF
 
275
d6.d6
 
276
.FI
 
277
 
 
278
.PP
 
279
Find the median of 3 d20s:
 
280
.IP
 
281
.NF
 
282
high 1 low 2 3#d20
 
283
.FI
 
284
 
 
285
.PP
 
286
3d6 with rerolls on 6s:
 
287
.IP
 
288
.NF
 
289
sum(while x=3#d6 do ((count ==6 x)#d6))
 
290
.FI
 
291
 
 
292
.PP
 
293
Roll 7 d10 and find the largest sum of identical dice:
 
294
.IP
 
295
.NF
 
296
let x = 7#d10 in high 1 (foreach y in 1..10 do sum (==y x))
 
297
.FI
 
298
 
 
299
.PP
 
300
The Fibonacci sequence is defined by Fn = Fn-1 + Fn-2, with F1 = F2 = 1.
 
301
Calculate the first twenty Fibonacci numbers:
 
302
.IP
 
303
.NF
 
304
let n = 20 in
 
305
  let f = (1,1) in
 
306
    foreach i in 1..n do
 
307
      let f = (f,sum(high 2 f)) in
 
308
        if ==n i then f else ()
 
309
.FI             
 
310
 
 
311
.PP
 
312
Risk has battles where the attacker rolls 3d6 and the defender rolls 2d6. 
 
313
The highest attacker die is matched with the highest defender die and the 
 
314
second highest attacker die to the second highest defender die. For both 
 
315
matches, the highest wins, with ties going to the defender. The number of 
 
316
attacker wins:
 
317
.IP
 
318
.NF
 
319
let a = 3#d6 in
 
320
  let b = 2#d6 in
 
321
    count( (<(high 1 a) high 1 b),
 
322
           (<(high 1 low 2 a) low 1 b))
 
323
.FI                
 
324
 
 
325
.PP
 
326
Storyteller die roll with target number 8 and botches indicated at -1:
 
327
.IP
 
328
.NF
 
329
let c=5#d10 in
 
330
  let succs = count >7 c in
 
331
    let ones = count ==1 c in
 
332
      if >0 succs then high 1 (0,succs-ones)
 
333
      else if >0 ones then -1 else 0
 
334
.FI       
 
335
 
 
336
.PP
 
337
Combat in Silent Death is rather complex. Three dice are rolled. If their 
 
338
sum is above a target, the roll is a hit. To calculate damage, the same dice 
 
339
are sorted. If all three are equal, all are summed to yield the damage. If 
 
340
the least two are equal, but the third is higher, the high die is the damage. 
 
341
If the two highest are equal, but the third is lower, the two high dice are 
 
342
summed to yield the damage. If all three dice are different, the middle die 
 
343
is the damage. This example assumes that the dice are two d8s and a d10, with 
 
344
a target number of 15:
 
345
.IP
 
346
.NF
 
347
let x = 2#d8,d10 in
 
348
  (count >15 sum x)#
 
349
    let a = low 1 x in               // low die
 
350
    let b = high 1 low 2 x in        // middle die
 
351
    let c = high 1 x in              // high die
 
352
      if ==a ==b c then a+b+c        // all equal
 
353
      else if ==a <c b then c        // two low equal
 
354
      else if >a ==c b then b+c      // two high equal
 
355
          else b                                                 // all different
 
356
.FI
 
357
 
 
358
.SH CREDITS
 
359
Dicelab is based on the excellent work "roll" by Torben Mogensen (http://www.diku.dk/~torbenm/Dice.zip). Without his work and comments, this would hardly ever have happened.
 
360
 
 
361
The current language specification and the extensions to the original language
 
362
are derived from the work of Joel Uckelman (http://dice.nomic.net/bones.html), 
 
363
most of the documentation is stolen from him as well.
 
364
 
 
365
This code was written by Robert Lemmen <robertle@semistable.com> who would be glad to hear your questions and remarks.