Provided by: dicelab_0.7-7_amd64 bug

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