WeightedRandom.Dice (weighted_random v1.0.0-rc.1)

Copy Markdown View Source

Creating Dice

alias WeightedRandom.{Dice, Die}
import Dice

# This creates 4 x 6-sided dice
# In standard dice notation this would be written as "4d6"
d = ~d{4, 6}

Now let's make the number 2 have more weight.

Dice always use outcome_type: :value, not :index, so the target is 2

d = ~d{4, 6}
weights = [%{target: 2, amount: 50}]
d = Dice.add_weight(d, weights)

# Always remember to roll again so the new weight takes effect.
d = Dice.roll(d)

IO.inspect(Dice.results(d), label: "results")
# => [2, 2, 3, 2]
d.total
# => 9

Summary

Functions

Adds weight to ALL dice in the Dice struct.

Take a list of Dice structs, and combine them without rerolling

Take two Dice structs, and combine them without rerolling

Manually create a Dice struct. This is a lower-level alternative to sigil_d/2. One advantage of using new/1 is that you can use different types of dice, with any combination of sides and weights.

Given some dice, return a list showing the result of each one.

Takes a Dice struct and rerolls it.

Convenience sigil for creating dice using standard notation.

Types

t()

@type t() :: %WeightedRandom.Dice{
  dice: [
    %WeightedRandom.Die{
      preprocessed: term(),
      result: term(),
      sides: term(),
      weights: term()
    }
  ],
  modifier: integer(),
  subtotal: integer(),
  total: integer()
}

Functions

add_weight(dice, weight)

@spec add_weight(t(), [WeightedRandom.Utils.Types.weight_spec()]) :: t()

Adds weight to ALL dice in the Dice struct.

Examples

iex> d = ~d{10, 20} 
iex> d = Dice.add_weight(d, [%{target: 2, weight: 50}])
iex> Enum.all?(d.dice, fn die -> die.weights == [%{target: 2, weight: 50}] end)
true

merge_dice(list)

@spec merge_dice([t()]) :: t()

Take a list of Dice structs, and combine them without rerolling

Examples

iex> d1 = ~d{2, 6}
iex> d2 = ~d{3, 10}
iex> d3 = Dice.merge_dice([d1, d2])
iex> is_struct(d3, Dice)
true

merge_dice(dice1, dice2)

@spec merge_dice(t(), t()) :: t()

Take two Dice structs, and combine them without rerolling

Examples

iex> d1 = ~d{2, 6}
iex> d2 = ~d{3, 10}
iex> d3 = Dice.merge_dice(d1, d2)
iex> is_struct(d3, Dice)
true

new(dice_spec)

Manually create a Dice struct. This is a lower-level alternative to sigil_d/2. One advantage of using new/1 is that you can use different types of dice, with any combination of sides and weights.

Eamples

iex> die = Die.new(%{sides: 6})
iex> dice = Dice.new(%{dice: [die]})
iex> %Dice{dice: [d]} = dice
iex> d == die
true

Takes a single map as an argument, with the following keys:

  • :modifier (integer/0) - A number added or subtracted from the total. The modifier is applied only once, even with multiple dice.

  • :dice (list of struct of type WeightedRandom.Die) - A list of WeightedRandom.Die structs to make up the collection of dice. They can be any combination of sides and weights.

results(dice)

@spec results(dice :: t()) :: [integer()]

Given some dice, return a list showing the result of each one.

Examples

d = ~d"4d6"
Dice.results(d) == [2, 5, 3, 4]

roll(d)

Takes a Dice struct and rerolls it.

Examples

dice = ~d{2, 12}
dice.total == 12

dice = Dice.roll(dice)
dice.total == 20

sigil_d(str, opts \\ [])

Convenience sigil for creating dice using standard notation.

Tuple format

Examples

iex> d = ~d{4,6,-1} # Equal to 4d6-1 in standard dice notation
iex> Enum.count(d.dice)
4
iex> Enum.all?(d.dice, &(&1.sides == 6))
true

String format

Examples

iex> d = ~d"2d8+3"
iex> Enum.count(d.dice)
2
iex> Enum.all?(d.dice, &(&1.sides == 8))
true