Mix.install(
  [
    {:weighted_random, "~> 1.0.0-alpha.2"},
  ]
)

Dice tutorial

Weighted Random can also implement dice.

alias WeightedRandom.{Dice, Die}
# Die is singular, Dice are plural.


import Dice
# This dice notation syntax is saying "Give me 3 dice, each with 6 sides"
dice = ~d"3d6"

%{
  results: Dice.results(dice),
  total: dice.total
}

Let's add weights to the dice.

Note that dice weights never target the index. only the actual value. In WeightedRandom.rand/3, that would be equal to passing in the opts [outcome_type: :value] automatically.

dice = Dice.add_weight(~d"10d6", [%{target: 5, amount: 5}])
       |> Dice.roll() # You must re-roll the dice or weights have no effect.

%{
  results: Dice.results(dice),
  total: dice.total
}

A quick note about the ~d sigil: You can add a modifier to the roll. This has no effect on the results, but it will change the total amount.

dice = ~d"2d6+3" # modifiers can also be negative. e.g. ~d"2d6-3"
%{
  results: Dice.results(dice),
  total: dice.total
}
# Another syntax is tuple.
dice = ~d{2, 6, -3}

%{
  results: Dice.results(dice),
  total: dice.total
}

You can combine different types of dice together.

d12s = Dice.add_weight(~d"2d12-1", [%{target: 12, amount: 144}])
d4s = Dice.add_weight(~d"2d4", [%{target: 4, amount: 16}])
dice = Dice.merge_dice([d12s, d4s])

dice = Dice.roll(dice)

%{
  results: Dice.results(dice),
  total: dice.total
}

It is even possible to create a single die. You must do that manually, without the ~d sigil.

d3 = Die.new(%{sides: 3})
d8 = Die.new(%{sides: 8, weights: [%{target: 8, amount: 10}]})

# a die cannot have modifiers. Only groups of dice.
# You can create dice from a list of individual die structs
dice = Dice.new(%{dice: [d3, d8], modifier: 1})
       |> Dice.roll()
%{
  results: Dice.results(dice),
  total: dice.total
}