I extended the example in 04-random.elm to support N dice and to draw the results using SVG.
import Html exposing (..)
import Html.Events exposing (..)
import Random
import List exposing (length, repeat, range)
import Svg exposing (Svg, svg, circle)
import Svg.Attributes exposing (..)
main =
Html.program {
init = init,
view = view,
update = update,
subscriptions = subscriptions
}
-- MODEL
type alias Model = {
dieFaces : List Int
}
init : (Model, Cmd Msg)
init =
let numDice = 5
in
(Model (repeat numDice 1), Cmd.none)
-- UPDATE
type Msg =
Roll |
NewFaces (List Int)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll -> (
model,
Random.generate NewFaces (
Random.list (length model.dieFaces) (Random.int 1 6)
)
)
NewFaces newFaces ->
(Model newFaces, Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div [] (
List.map drawFace model.dieFaces
++ [ button [ onClick Roll ] [ text "Roll" ] ]
)
drawFace : Int -> Html Msg
drawFace numDots =
div [ style "width: 66px; height: 66px; padding: 10px" ] [
svg
[ version "1.1", width "66", height "66" ]
(drawDice ::
(List.map (\i -> drawDot i numDots) (range 0 (numDots - 1))))
]
drawDice: Svg Msg
drawDice =
circle [ fill "gold", stroke "orange", strokeWidth "3", cx "33", cy "33", r "30" ] []
drawDot: Int -> Int -> Svg Msg
drawDot i n =
circle [ fill "black", cx (toString (posX i n)), cy (toString (posY i n)), r "5" ] []
posX: Int -> Int -> Int
posX i n =
round (33 + (15 * cos (6.28 * (toFloat(i) / toFloat(n)))))
posY: Int -> Int -> Int
posY i n =
round (33 + (15 * sin (6.28 * (toFloat(i) / toFloat(n)))))