Man Linux: Main Page and Category List

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

       --print-tree, -p
              print the parse tree (for debugging purposes)

       --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, -c
              specify the number of rerolls for --eval, default it 10000

       -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 <robertle@semistable.com> who
       would be glad to hear your questions and remarks.