# SnakeEyes documentation

SnakeEyes is a web-based calculator for dice probabilities. You write a small program that describes how to roll the dice, and it computes all the possible outcomes and their probabilities. It can also draw graphs to display the results.

This is a complete reference documentation. To learn how to use SnakeEyes, you might want to read the tutorials and examples first.

## Introduction

Programs in SnakeEyes are written in the Lua programming language. The tool is actually a full-featured Lua 5.3 interpreter that includes a dice probabilities computation library, graphing tools and convenient shortcuts.

You can refer to the reference manual for Lua 5.3 for any questions concerning the language itself.

This documentation describes essentially the dice probabilities library and the environment setup for the web tool, which provides a few global functions, and introduces two object classes: `Die` and `DiceCollection`.

## Automatic conversion

Throughout the library, wherever a `Die` object is expected, one can provide a single value instead (number, string, boolean or array of numbers), and it will be converted to a `Die` object with that single outcome.

Similarly, instead of a `Die`, one can provide a `DiceCollection`, which will be converted to a single `Die` via the `sum` method.

## Nested dice

When creating a die with `d(outcomes)`, outcomes can be themselves `Die` objects. In that case, the nested dice are flattened: it corresponds to the idea of replacing the result with the outcome of another die. For instance, `d{1,2,3,d6}` concisely expresses “roll a d4, and if a 4 comes up, roll a d6 instead”.

Similarly, the function passed to `apply` can return `Die` objects instead of single values.

## Global functions

### d(n)

Returns a `Die` object with outcomes 1 to `n`, all equiprobable.

### d(outcomes [, probabilities])

Returns a `Die` object with given `outcomes`, and given relative `probabilities` (defaults to equiprobable). Outcomes can be numbers, string, booleans, arrays of numbers, or other `Die` objects. Different types of outcomes cannot be mixed in a single `Die`.

### dN

All globals `d1`, `d2`, `d3`, etc. (`d` followed by any number of digits) are pre-defined to the same result as `d(N)`.

### abs, acos, …

The entire contents of the Lua `math` library are in the global environment: `abs`, `acos`, `asin`, `atan`, `ceil`, `cos`, `deg`, `exp`, `floor`, `fmod`, `huge`, `log`, `max`, `maxinteger`, `min`, `mininteger`, `modf`, `pi`, `rad`, `random`, `randomseed`, `sin`, `sqrt`, `tan`, `tointeger`, `type`, `ult`

### write

Although the `io` library is not available, the `write` function is provided to replace `io.write`, and works similarly. `print` works as usual (placing tabs between its arguments).

### plot(die [, label])

Plots a single die: probabilities as a bar chart, and for a numerical die, the two cumulative distributions overlaid as lines. The optional `label` string is used in the plot’s legend.

### plot(die1 [, label1], die2 [, label2], …)

Plots the probabilities for multiple dice in a single plot, as lines. Each die can be followed by an optional string argument that will be used a label in the legend.

### plot_cdf(die1 [, label1], die2 [, label2], …)

Similar to `plot` for multiple dice, but plots the cumulative distributions instead (probabilities of outcomes lower than or equal). Cannot be used with non numerical dice.

Alternatively, the function can take a single table argument containing the dice and labels.

### plot_cdf2(die1 [, label1], die2 [, label2], …)

Similar to `plot` for multiple dice, but plots the opposite cumulative distributions instead (probabilities of outcomes greater than or equal). Cannot be used with non numerical dice.

Alternatively, the function can take a single table argument containing the dice and labels.

### plot_transposed(die1 [, label1], die2 [, label2], …)

Plots multiple dice so that each die is a column of all its outcomes in a stacked bar chart. This can be useful to visualize and compare dice with a low number of outcomes.

Alternatively, the function can take a single table argument containing the dice and labels.

### plot_raw(labels, datasets, stacked, percentage)

The library exposes the internal plotting function, for maximum flexibility. `labels` is an array of labels (the X axis) and `datasets` is an array containing the datasets to plot. Each dataset should be an array of values (same size as `labels`) and can optionally contain the following fields:

• `label`: the name to use for the dataset in the legend
• `type`: by default the charts are bars, but this can be set to the string `"line"` or `"scatter"` instead

If `stacked` is true, the graph will be stacked bars and/or lines, and if `percentage` is true, the Y axis will be displayed as percentages instead of direct values.

A convenience function that will simply print the dice one after the other, preceded with their labels if any.

Alternatively, the function can take a single table argument containing the dice and labels.

In other words, it takes exactly the same arguments as the plot functions, and can be used to easily print out the same data that you plot.

## `Die` object

### Die:summary()

Returns a string that summarizes the die: the outcomes with their probabilities, as well as the cumulative distributions and common statistics for numerical dice.

This is what is also returned when a `Die` is converted to a string using `tostring` (and therefore when using `print` or `write`).

### Die:compute_stats()

Returns a table with the following fields:

• `outcomes`: the sorted list of possible outcomes of this die (note that strings can be compared and sorted lexicographically in Lua)
• `probabilities`: the probabilities associated with the outcomes, in the same order
• `lte`: the cumulative distribution, that is, for each outcome, the probability of getting this outcome or a lower one (in the same order as `outcomes`)
• `gte`: the other cumulative distribution: for each outcome, the probability of getting this outcome or a higher one (in the same order as `outcomes`)

For dice with numerical outcomes, the table also has these fields:

• `average`: the average or expectation of the die
• `stdev`: the standard deviation

Fields `lte` and `gte` are omitted for boolean dice, and the `outcomes` table is not sorted, since booleans cannot be ordered.

### Die:percentile(n)

Computes the `n`-th percentile (with `n` between 0 and 1).

### Die:apply(func)

Returns a new `Die` by applying the given function to each outcome.

### Die:combine(other, func)

Returns a new `Die` by applying the given function to each possible combinations of outcomes of the die and the `other` die.

### ..

The concatenation operator is overloaded so that `a .. b` returns a `DiceCollection` made of dice `a` and `b`.

### Arithmetic operators

The usual arithmetic operators `+` `-` `*` `/` `//` `^` and `%` are overloaded for the `Die` object, and correspond to applying the given operations to the two operands.

The `*` operator is an exception: if the left-hand side operand is a number N, the result is instead a `DiceCollection` containing N repetitions of the right-hand side operand.

The `-` operator also works as the unary operator for negation.

• `lt` for operator `<`
• `lte` for operator `<=`
• `gt` for operator `>`
• `gte` for operator `>=`
• `eq` for operator `==`
• `neq` for operator `~=`

so that for instance `a:lt(b)` is equivalent to `(a .. b):apply(function(x,y) return x < y end)`.

### Die(outcome)

A `Die` object can be called like a function to get the probability of the given `outcome`. This will of course return 0 if the outcome is not possible on this die.

### Die:explode(condition, rerolls)

The common “explosion” dice mechanic: roll the die, and if the outcome matches the `condition`, reroll and add the result. Keep rerolling as long as the new results match condition, within the limit of `rerolls`.

`condition` can either be a function (returning true for the outcomes that trigger the reroll), or a single value (the only outcome that triggers a reroll).

### Die:sum()

For a die with arrays of numbers as outcomes, return a new die whose outcomes are the sums of these arrays.

## `DiceCollection` object

`DiceCollection` objects are created with the `..` operator for `Die` and `DiceCollection` (eg. `a .. b .. c`), or multiplying a die to the left by a number (`4 * d5`).

The core methods for `DiceCollection` are `apply` and `accumulate`. Every other method is provided as a convenient shortcut for common dice computations. Note that `apply` goes through every possible combination of outcomes of the entire collection, which is much less efficient than `accumulate`, which combines the dice one by one.

Whenever possible, it is recommended to avoid `apply` and use either `accumulate`, or any of the other built-in methods which are based on it.

### DiceCollection:apply(func)

This is the main way to transform and combine dice. `apply` enumerates all possible combinations of outcomes for the dice in the collection, along with the probability of each such combination. It returns a new `Die` object where outcomes are the results of calling function `func` on each combination of outcomes.

### DiceCollection:accumulate(func)

Combines the first two dice of the collection using `func`, then the result and the third die, then the result of that and the fourth die, etc.

This can be used to compute efficiently some common operations that can be done die by die instead of rolling all the dice first and applying the operation to the result.

See for instance `sum`, which is defined exactly as `collection:accumulate(function(x,y) return x + y end)`.

### DiceCollection:sum()

Returns the `Die` which is the sum of all dice in the collection.

### DiceCollection:count(value, [value2, [value3, …]])

Counts occurrences of `value` in the outcomes of the dice of the collection. Alternatively, `value` can be a function, in which case `count` counts the number of outcomes for which that function returns true.

If more than one value or function are provided, `count` returns an array-valued die, where the outcomes are all the combinations of counts, in the same order.

### DiceCollection:none(value)

Returns a boolean die indicating the probability of getting any/all/no outcome equal to `value`. Similarly to `count`, `value` can be a function, in which case the die describes the probability of any/all/no outcome to return true when passed to that function.

### DiceCollection:lowest([n])

Computes the distributions of the highest/lowest outcomes.

If `n` is provided, these return array-valued dice of the distributions of the `n` highest/lowest outcomes.

### DiceCollection:sort()

The distribution of the sorted outcomes of the dice.

### DiceCollection:drop_lowest([n])

The common operation of rolling the dice, removing the `n` highest/lowest results, and adding the rest. `n` defaults to 1.