Loaded dice: weighted random choices in constant time.
A die is built once from outcomes and their weights with Vose's alias method, in integer arithmetic. Rolling it takes a single uniform random integer, whatever the number of outcomes or how skewed their weights, so the maze can draw thousands of words per page cheaply.
Rolls take and return an explicit :rand state, so a page seeded from its
path draws the same outcomes every time.
iex> die = Limen.Maze.Dice.new([{:heads, 1}, {:tails, 3}])
iex> {outcome, _state} = Limen.Maze.Dice.roll(die, :rand.seed_s(:exsss, 42))
iex> outcome in [:heads, :tails]
true
Summary
Functions
Builds a die from {outcome, weight} pairs with positive integer weights.
Rolls the die, returning an outcome and the next random state.
The number of outcomes.
Types
@type t() :: %Limen.Maze.Dice{ aliases: tuple(), outcomes: tuple(), size: pos_integer(), thresholds: tuple(), total: pos_integer() }
Functions
@spec new([{term(), pos_integer()}, ...]) :: t()
Builds a die from {outcome, weight} pairs with positive integer weights.
@spec roll(t(), :rand.state()) :: {term(), :rand.state()}
Rolls the die, returning an outcome and the next random state.
@spec size(t()) :: pos_integer()
The number of outcomes.