johnathanbostrom/elm-dice/2.0.0

Dice

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

Definition

roll : Int -> Dice -> 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 Int
| DicePool String (Generator RollResult)
| CustomDie String (List Int)
| WeightedDie String (List ( Float, Int ))
| Constant String 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 : 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 }
        ]
}
= Empty
| RollResults (List RollResult)

represents the children of a RollResult.

Combining and Transforming Rolls

dropLowest : Generator RollResult -> 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 -> Bool) -> Generator RollResult -> 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 -> Bool) -> Generator RollResult -> 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.

(RollResult -> Bool)
-> Keep
-> Generator RollResult
-> 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
(RollResult -> Generator RollResult)
-> Generator RollResult
-> 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

Generator RollResult
-> Generator RollResult
-> 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 -> Int) -> Generator RollResult -> 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 -> Generator Int -> Generator RollResult

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