lue-bird / elm-state-interface / Web.Random

Helpers for randomness as part of an Interface. Not familiar with random "generators"? elm/random explains it nicely!

Here's an example showing a number between 1 and 6 and a button to reroll using NoRedInk/elm-random-pcg-extended

import Random.Pcg.Extended
import Web.Dom

type State
    = WaitingForInitialRandomness
    | DiceUiState { diceEyes : Int, seed : Random.Pcg.Extended.Seed }

type DiceUiEvent
    = RerollClicked

diceEyesRandomGenerator : Random.Pcg.Extended.Generator Int
diceEyesRandomGenerator =
    Random.Pcg.Extended.int 1 6

{ initialState = WaitingForInitialRandomness
, interface =
    \state ->
        case state of
            WaitingForInitialRandomness ->
                Web.Random.unsignedInt32s 4
                    |> Web.interfaceFutureMap
                        (\unsignedInt32s ->
                            let
                                initialSeed : Random.Pcg.Extended.Seed
                                initialSeed =
                                    Random.Pcg.Extended.initialSeed (unsignedInt32s |> List.head |> Maybe.withDefault 0) (unsignedInt32s |> List.drop 1)

                                ( diceEyes, newSeed ) =
                                    Random.Pcg.Extended.step diceEyesRandomGenerator initialSeed
                            in
                            DiceUiState { diceEyes = diceEyes, seed = newSeed }
                        )

            DiceUiState randomStuff ->
                Web.Dom.element "div"
                    []
                    [ randomStuff.diceEyes |> String.fromInt |> Web.Dom.text
                    , Web.Dom.element "button"
                        [ Web.Dom.listenTo "click"
                            |> Web.Dom.modifierFutureMap (\_ -> RerollClicked)
                        ]
                        [ Web.Dom.text "roll the dice" ]
                    ]
                    |> Web.Dom.render
                    |> Web.interfaceFutureMap
                        (\RerollClicked ->
                            let
                                ( diceEyes, newSeed ) =
                                    Random.Pcg.Extended.step diceEyesRandomGenerator randomStuff.seed
                            in
                            DiceUiState { diceEyes = diceEyes, seed = newSeed }
                        )
}

unsignedInt32s : Basics.Int -> Web.Interface (List Basics.Int)

An Interface for generating a given count of cryptographically sound unsigned 32-bit Ints. You can use these in all kinds of packages that allow creating an initial seed from ints like NoRedInk/elm-random-pcg-extended

Note: uses window.crypto.getRandomValues