dicelab(1) | Dicelab - examine and roll dice | dicelab(1) |
dicelab - roll and examine dice rolling schemes
dicelab [options] [-f <file>]
Dicelab reads a description of a dice rolling scheme from a file or from stdin if no file is specified and then rolls or examines this scheme.
Single die rolls may be made using the 'd' operator, followed by the number of faces on the die to be rolled. E.g., d6 will roll a single six-sided die, and d2 will flip a coin. Expressions may be modified by the standard arithmetic operators. d10-1 will yield a value between 0 and 9, inclusive. In order to roll multiple dice of the same type, use the repetition operator '#'. 2#d6 will roll two six-sided dice; this is not the same as 2*d6, which rolls only a single die but multipies the result by two, or 2d6 which will cause a syntax error. In order to get the sum of two six-sided dice, do sum(2#d6).
<integer> ::= -?[0-9]+ <variable> ::= [A-Za-z]+ <scalar> ::= <integer> | <variable> | ( <scalar> ) | - <scalar> | <scalar> + <scalar> | <scalar> - <scalar> | <scalar> * <scalar> | <scalar> / <scalar> | <scalar> % <scalar> | <scalar> ^ <scalar> | <scalar> . <scalar> | d<scalar> | sum <expr> | prod <expr> | count <expr> <list> ::= <scalar> # <expr> | ( <list> ) | <scalar> .. <scalar> | <expr> , <expr> | perm <expr> | sort <expr> | rev <expr> | (drop|keep)? low <scalar> <expr> | (drop|keep)? high <scalar> <expr> | (drop|keep)? first <scalar> <expr> | (drop|keep)? last <scalar> <expr> | (drop|keep)? == <scalar> <expr> | (drop|keep)? != <scalar> <expr> | (drop|keep)? < <scalar> <expr> | (drop|keep)? > <scalar> <expr> | (drop|keep)? <= <scalar> <expr> | (drop|keep)? >= <scalar> <expr> | if <expr> then <expr> else <expr> | let <variable> = <expr> in <expr> | while <variable> = <expr> do <expr> | foreach <variable> in <expr> do <expr> <expr> ::= <scalar> <list> <input> ::= <expr> | <expr> ; <expr>
Comments may be inserted by using double slashed (//) as in C.
+ - * / ^
-
%
.
d
sum prod
count
#
..
,
sort
perm
rev
low high
first last
== != < > <= >=
drop keep
let
foreach
while
if
Count the number of dice greater than 7:
count >7 5#d10
Count the number of dice greater than 7 minus the number of dice equal to 1:
let c=5#d10 in (count >7 c)-(count ==1 c)
Count the number of rolls until a 6 is rolled:
count (while x=d6 do ((count <6 x)#d6))
Count the number of rolls until a 6 is rolled, more efficiently:
count (while x=(d6/6) do ((count <1 x)#(d6/6)))
Roll attributes for a new D&D character:
6#sum(drop low 1 4#d6)
Roll on the 11..66 morale check table in The Gamers' Civil War Brigade Series:
d6.d6
Find the median of 3 d20s:
high 1 low 2 3#d20
3d6 with rerolls on 6s:
sum(while x=3#d6 do ((count ==6 x)#d6))
Roll 7 d10 and find the largest sum of identical dice:
let x = 7#d10 in high 1 (foreach y in 1..10 do sum (==y x))
The Fibonacci sequence is defined by Fn = Fn-1 + Fn-2, with F1 = F2 = 1. Calculate the first twenty Fibonacci numbers:
let n = 20 in let f = (1,1) in foreach i in 1..n do let f = (f,sum(high 2 f)) in if ==n i then f else ()
Risk has battles where the attacker rolls 3d6 and the defender rolls 2d6. The highest attacker die is matched with the highest defender die and the second highest attacker die to the second highest defender die. For both matches, the highest wins, with ties going to the defender. The number of attacker wins:
let a = 3#d6 in let b = 2#d6 in count( (<(high 1 a) high 1 b), (<(high 1 low 2 a) low 1 b))
Storyteller die roll with target number 8 and botches indicated at -1:
let c=5#d10 in let succs = count >7 c in let ones = count ==1 c in if >0 succs then high 1 (0,succs-ones) else if >0 ones then -1 else 0
Combat in Silent Death is rather complex. Three dice are rolled. If their sum is above a target, the roll is a hit. To calculate damage, the same dice are sorted. If all three are equal, all are summed to yield the damage. If the least two are equal, but the third is higher, the high die is the damage. If the two highest are equal, but the third is lower, the two high dice are summed to yield the damage. If all three dice are different, the middle die is the damage. This example assumes that the dice are two d8s and a d10, with a target number of 15:
let x = 2#d8,d10 in (count >15 sum x)# let a = low 1 x in // low die let b = high 1 low 2 x in // middle die let c = high 1 x in // high die if ==a ==b c then a+b+c // all equal else if ==a <c b then c // two low equal else if >a ==c b then b+c // two high equal else b // all different
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.
The current language specification and the extensions to the original language are derived from the work of Joel Uckelman (http://dice.nomic.net/bones.html), most of the documentation is stolen from him as well.
This code was written by Robert Lemmen <robertle@semistable.com> who would be glad to hear your questions and remarks.
February 2007 | dicelab v0.2 |