This is the command dicelab that can be run in the OnWorks free hosting provider using one of our multiple free online workstations such as Ubuntu Online, Fedora Online, Windows online emulator or MAC OS online emulator

**PROGRAM:**

**NAME**

dicelab - roll and examine dice rolling schemes

**SYNOPSIS**

**dicelab**

__[options]__

__[-f__

__<file>]__

**OPTIONS**

**-h**,

**--help**,

**-?**

print a help message

**--version**,

**-v**

display version number

**--calc**,

**-c**

calculate the distribution

**--roll**,

**-r**

roll the dice as specified. This will also be used if no other action is requested

**--eval**,

**-e**

reroll many times and sum up the results to get a statistical distribution of

values

**--count**,

**-n**

specify the number of rerolls for --eval, default it 10000

**--print-tree**,

**-p**

print the parse tree (for debugging purposes)

**-f**<file>

read the scheme description from file instead from stdin

**DESCRIPTION**

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.

**QUICK** **START**

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).

**FULL** **SYNTAX**

<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.

**SEMANTICS**

**+**

**-**

*****

**/**

**^**

These are the familiar binary arithmetic operators for addition, subtraction,

multiplication, division, and exponentiation. Division rounds toward zero.

Examples: 5+7, d6-1, 2^10

**-**

This is the unary minus operator. Examples: -1

**%**

This is the modulus operator. x % y gives the remainder of x divided by y.

Examples: 11%2, d6%3

**.**

This is the scalar concatenation operator. x . y gives xy, the concatenation of x

and y. Examples: -10.9, d6.d6

**d**

This is the die roll operator. dn gives the value of a single roll of an n-sided

die. Examples: d6, 2#d6

**sum**

**prod**

These are the extended sum and product operators. If e is an expression, sum e and

prod e give the sum of the members of e and the product of the members of e,

respectively. Examples: sum(1..100), prod(3#d6)

**count**

This is the list size operator. If e is an expression, then count e gives the

number of members of e. Examples: count(1,2,3), count(== 6 10#d6)

**#**

This is the list repetition operator. If n is a nonnegative scalar and e is an

expression, then n#e is a list containing the results of n evaluations of e.

Examples: 10#8, 3#d10

**..**

This is the range operator. If x and y are scalars, then x..y is a list consisting

of the interval [x,y]. If x>y, then the resulting list is empty. Examples: 1..10,

4..d10

**,**

This is the list concatenation operator. v,u gives the list consisting of all of

the members of v, followed by all of the members of u. Examples: 1,2 4,(3#d6)

**sort**

This is the list sorting operator. sort e sorts the list e in ascending order.

Examples: sort(10#d6)

**perm**

This is the list permutation operator. sort e results in a random permutation of

the list e. Use perm to shuffle a list. Examples: perm(1..52)

**rev**

This is the list reversal operator. rev e results in a list with the same members

as the list e, but in reverse order. Examples: rev(1..10), rev sort(10#d8)

**low**

**high**

These operators act as filters by finding the least and greatest values in lists.

If n is a nonnegative scalar and e is an expression, then low n e gives the n least

members of e, and high n e gives the n greatest members of e. Examples: high 3 5#d6

**first**

**last**

These operators act as filters by finding initial and final segments of lists. If n

is a nonnegtive scalar and e is an expression, then first n e gives the first n

members of e, and last n e gives the last n members of e. Examples: first 3

(1..10)

**==**

**!=**

**<**

**>**

**<=**

**>=**

These operators act as filters by finding values in lists which meet given

conditions. If x is a scalar and e is an expression, then == x e gives the list of

members of e equal to x; != x e gives the list of members of e not equal to x; < x

e gives the list of members of e less than x; > x e gives the list of members of e

greater than x; <= x e gives the list of members of e less than or equal to x; >= x

e gives the list of members of e greater than or equal to x. Examples: >= 3 5#d6

**drop**

**keep**

These operators modify filters on lists. If fop is a filter operation on an

expression e, then keep fop e has the same result as fop e and drop fop e evaluates

to e less keep fop e. In other words, drop negates filter conditions, and keep

affirms them. keep is never necessary and exists only for symmetry. Examples:

sum(drop low 1 4#d6)

**let**

This is the variable assignment and substitution operator. If x is a variable and e

and f are an expressions, then let x = e in f gives the list which results from

evaluating f with the value of e substituted for every occurance of x in f.

Evaluation of e is done prior to substitution. Examples: let x = d6 in x*x

**foreach**

This is the bounded iteration operator. If x is a variable and e and f are

expressions, then foreach x in e do f gives the list which results from assigning

to x each of the members of e and evaluating f. Examples: foreach x in c do x+1

**while**

This is the unbounded iteration operator. If x is a variable and e and f are

expressions, then while x = e do f is the list v0,v1,...,vn, where v0 is the result

of evaluating e and vi+1 is the result of assigning vi to x and evaluating f,

stopping at the first vi which is empty. Examples: while x=d6 do ((count <6 x)#d6)

**if**

This is the branching operator. If e, f, and g are expressions, then if e then f

else g gives f if e is nonempty, and g otherwise. Examples: if count(>4 2#d6) then

1 else 0

**EXAMPLES**

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

**CREDITS**

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 <[email protected]> who would be glad to hear

your questions and remarks.

Use dicelab online using onworks.net services