johnathanbostrom / elm-dice / Dice

A Dice Roller Package based on elm/random that allows you to build customizable dice rolling functions in a readable way.

Definition

roll : Basics.Int -> Dice -> Random.Generator RollResult

make a Random.Generator for a roll of n dice. if n < 1, this will return Constant "No Dice" 0

roll 3 D6


type Dice
    = D4
    | D6
    | D8
    | D10
    | D12
    | D20
    | D100
    | DX Basics.Int
    | DicePool String (Random.Generator RollResult)
    | CustomDie String (List Basics.Int)
    | WeightedDie String (List ( Basics.Float, Basics.Int ))
    | Constant String Basics.Int

Represents a Die or pool of dice. Most common dice are built in, but you can also create your own.

-- A 5 sided die.
d5 =
    DX 5

-- A custom die
customDie =
    CustomDie "EvenRoller" [ 2, 2, 2, 2, 4, 4, 4, 6, 6, 8 ]

-- A weighted die. Effectively the same as the customDie above.
weightedDie =
    WeightedDie "EvenRoller"
        [ ( 4, 2 )
        , ( 3, 4 )
        , ( 2, 6 )
        , ( 1, 8 )
        ]

-- A Constant Value
always4 =
    Constant "Four" 4


type alias RollResult =
{ description : String
, value : Basics.Int
, children : ChildrenRolls 
}

Represents the results of a roll.

--possible result of `roll 1 D6`:
{ descripion = "1D6"
, value = 4
, children = Empty
}

--possible result of `roll 2 D6`:
{ description = "3D6"
, value = 8
, children =
    RollResults
        [ { description = "1D6", value = 3, children = Empty }
        , { description = "1D6", value = 5, children = Empty }
        ]
}


type ChildrenRolls
    = Empty
    | RollResults (List RollResult)

represents the children of a RollResult.

Combining and Transforming Rolls

dropLowest : Random.Generator RollResult -> Random.Generator RollResult

Recalculates the value of a RollResult by dropping the lowest value of its children. If the RollResult had no children (because it was the result of a single die roll or constant value), Then dropLowest will set the value to zero.

statGenerator =
    roll 4 D6 |> dropLowest

countSuccessesIf : (RollResult -> Basics.Bool) -> Random.Generator RollResult -> Random.Generator RollResult

Recalculates the value of a RollResult by counting the number of children that pass the test.

    roll 3 D10
        |> countSuccessesIf (\r -> r > 7)

explodeIf : (RollResult -> Basics.Bool) -> Random.Generator RollResult -> Random.Generator RollResult

"explodes" a RollResult. An exploding die will keep rolling as long as it satisfies the predicate. For instance, if you roll a 10 on the following D10, you will roll again and add the rolls together. If your reroll is another D10, you repeat this process.

--defines a ten sided die that "explodes" on a 10.
explodingDie =
    roll 1 D10
        |> ExplodeIf (\r -> r == 10)

Currently, all dice are limited to 100 explosions.

rerollIf : (RollResult -> Basics.Bool) -> Keep -> Random.Generator RollResult -> Random.Generator RollResult

Rerolls a RollResult if it satisfies the given predicate. The value of one roll will be kept using the Keep rules specified.

-- rerolls any ones or twos, keeping the new result even if lower.
    roll 2 D6
    |> RerollIf (\r -> r.value < 2) New

andThen : (RollResult -> Random.Generator RollResult) -> Random.Generator RollResult -> Random.Generator RollResult

used to apply transformations to RollResult generators.


type Keep
    = Low
    | High
    | New
    | KeepCustom (List RollResult -> RollResult)

Represents how we decide when choosing between multiple die results. see RerollIf

plus : Random.Generator RollResult -> Random.Generator RollResult -> Random.Generator RollResult

combine the results of two rolls. The value of the resulting roll will be the sum of the values of those two rolls.

d6PlusD4 =
    roll 1 D6
        |> plus (roll 1 D4)
            --one possible result:
            { description = "1D6 + 1D4"
            , value = 8
            , children =
                RollResults
                    [ { description = "1D6", value = 6, children = Empty }
                    , { description = "1D4", value = 2, children = Empty }
                    ]
            }

mapValue : (RollResult -> Basics.Int) -> Random.Generator RollResult -> Random.Generator RollResult

Recomputes the value of a RollResult given the rule provided.

--rules for computing RollResult value
multiplyRolls rollResult =
    case rollResult.children of
        Empty ->
            0
        RollResults rolls ->
            gatherEqualsBy .value rolls
                |> map (\x -> x.left.value * (List.length x.right + 1))
                |> sum

-- rolls 4 D6, multiplying each result by the number of times it was rolled.
roll 4 D6
    |> mapValue multiplyRolls

Common Helpers

toRollResultGenerator : String -> Random.Generator Basics.Int -> Random.Generator RollResult

Converts a Random.Generator Int into a Random.Generator RollResult.