榆树指南骰子练习
Elm Guide Dice Exercise
我正在做随机部分的 Elm Guide 练习,但卡在了第 5 步,我必须在骰子确定最终值之前翻转骰子。我正在尝试调用 Cmd,它使用骰子的新值更新视图,只需单击“滚动!”按钮 10 次。并在每次迭代之前放置某种睡眠函数。据我所知,Elm 没有 for、loop 或 while 语句。循环的唯一方法是通过递归,但我无法为此调整我的代码。我的代码如下,有人有什么建议吗?
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Svg exposing (..)
import Svg.Attributes as SvgAttr exposing (..)
import Random
-- MAIN
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- MODEL
type alias Model =
{ dieFace : Int
, dieFace2 : Int
}
init : () -> (Model, Cmd Msg)
init _ =
( Model 1 1
, Cmd.none
)
-- UPDATE
type Msg
= Roll
| NewFace (Int, Int)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
( model
, Random.generate NewFace randomPair
)
NewFace (newFace, newFace2) ->
( Model newFace newFace2
, Cmd.none
)
weightedRoll : Random.Generator Int
weightedRoll =
Random.weighted
(1, 1)
[ (10, 2)
, (10, 3)
, (10, 4)
, (20, 5)
, (40, 6)
]
randomPair : Random.Generator (Int, Int)
randomPair =
Random.pair (Random.int 1 6) (Random.int 1 6)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ h1 [] [ Html.text (String.fromInt model.dieFace) ]
, svg
[ width "120"
, height "120"
, viewBox "0 0 120 120"
]
(List.append
[ rect
[ x "10"
, y "10"
, width "100"
, height "100"
, rx "15"
, ry "15"
]
[]
]
(dicesSVG model.dieFace)
)
, div []
[ h1 [] [Html.text (String.fromInt model.dieFace2) ]
, svg
[ width "120"
, height "120"
, viewBox "0 0 120 120"
]
(List.append
[ rect
[ x "10"
, y "10"
, width "100"
, height "100"
, rx "15"
, ry "15"
]
[]
]
(dicesSVG model.dieFace2)
)]
, button [onClick Roll] [Html.text "Roll!"]
]
dicesSVG : Int -> List (Svg Msg)
dicesSVG number =
case number of
1 ->
[ circle [cx "60", cy "60", r "10", fill "white" ] [] ]
2 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
3 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "60", cy "60", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
4 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "35", r "10", fill "white" ] []
, circle [ cx "35", cy "85", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
5 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "35", r "10", fill "white" ] []
, circle [ cx "60", cy "60", r "10", fill "white" ] []
, circle [ cx "35", cy "85", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
6 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "35", r "10", fill "white" ] []
, circle [ cx "35", cy "60", r "10", fill "white" ] []
, circle [ cx "85", cy "60", r "10", fill "white" ] []
, circle [ cx "35", cy "85", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
_ ->
[]
诀窍主要在于要求运行时向您发送消息。
您可以尝试的第一件事是改变
NewFace (newFace, newFace2) ->
( Model newFace newFace2
, Cmd.none
)
到
NewFace (newFace, newFace2) ->
( Model newFace newFace2
, Random.generate NewFace randomPair
)
这有一个永不停止的问题,让你的程序永远旋转...
因此您需要跟踪一些停止条件。也许在您的模型中添加一个字段来跟踪它已经滚动了多少次?然后根据该字段在 Random.generate
和 Cmd.none
之间切换。
最后,如果你想在滚动之间有时间延迟,那么
import Task
wait : Float -> msg -> Cmd msg
wait delay msgToCallWhenDone =
Task.perform (always msg) (Process.sleep delay)
会给你一个 Cmd
,它将在 delay
毫秒后调用你给它的任何消息。作为提示,您可能想为此介绍另一条信息。
我正在做随机部分的 Elm Guide 练习,但卡在了第 5 步,我必须在骰子确定最终值之前翻转骰子。我正在尝试调用 Cmd,它使用骰子的新值更新视图,只需单击“滚动!”按钮 10 次。并在每次迭代之前放置某种睡眠函数。据我所知,Elm 没有 for、loop 或 while 语句。循环的唯一方法是通过递归,但我无法为此调整我的代码。我的代码如下,有人有什么建议吗?
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Svg exposing (..)
import Svg.Attributes as SvgAttr exposing (..)
import Random
-- MAIN
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- MODEL
type alias Model =
{ dieFace : Int
, dieFace2 : Int
}
init : () -> (Model, Cmd Msg)
init _ =
( Model 1 1
, Cmd.none
)
-- UPDATE
type Msg
= Roll
| NewFace (Int, Int)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
( model
, Random.generate NewFace randomPair
)
NewFace (newFace, newFace2) ->
( Model newFace newFace2
, Cmd.none
)
weightedRoll : Random.Generator Int
weightedRoll =
Random.weighted
(1, 1)
[ (10, 2)
, (10, 3)
, (10, 4)
, (20, 5)
, (40, 6)
]
randomPair : Random.Generator (Int, Int)
randomPair =
Random.pair (Random.int 1 6) (Random.int 1 6)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ h1 [] [ Html.text (String.fromInt model.dieFace) ]
, svg
[ width "120"
, height "120"
, viewBox "0 0 120 120"
]
(List.append
[ rect
[ x "10"
, y "10"
, width "100"
, height "100"
, rx "15"
, ry "15"
]
[]
]
(dicesSVG model.dieFace)
)
, div []
[ h1 [] [Html.text (String.fromInt model.dieFace2) ]
, svg
[ width "120"
, height "120"
, viewBox "0 0 120 120"
]
(List.append
[ rect
[ x "10"
, y "10"
, width "100"
, height "100"
, rx "15"
, ry "15"
]
[]
]
(dicesSVG model.dieFace2)
)]
, button [onClick Roll] [Html.text "Roll!"]
]
dicesSVG : Int -> List (Svg Msg)
dicesSVG number =
case number of
1 ->
[ circle [cx "60", cy "60", r "10", fill "white" ] [] ]
2 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
3 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "60", cy "60", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
4 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "35", r "10", fill "white" ] []
, circle [ cx "35", cy "85", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
5 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "35", r "10", fill "white" ] []
, circle [ cx "60", cy "60", r "10", fill "white" ] []
, circle [ cx "35", cy "85", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
6 ->
[ circle [ cx "35", cy "35", r "10", fill "white" ] []
, circle [ cx "85", cy "35", r "10", fill "white" ] []
, circle [ cx "35", cy "60", r "10", fill "white" ] []
, circle [ cx "85", cy "60", r "10", fill "white" ] []
, circle [ cx "35", cy "85", r "10", fill "white" ] []
, circle [ cx "85", cy "85", r "10", fill "white" ] []
]
_ ->
[]
诀窍主要在于要求运行时向您发送消息。
您可以尝试的第一件事是改变
NewFace (newFace, newFace2) ->
( Model newFace newFace2
, Cmd.none
)
到
NewFace (newFace, newFace2) ->
( Model newFace newFace2
, Random.generate NewFace randomPair
)
这有一个永不停止的问题,让你的程序永远旋转...
因此您需要跟踪一些停止条件。也许在您的模型中添加一个字段来跟踪它已经滚动了多少次?然后根据该字段在 Random.generate
和 Cmd.none
之间切换。
最后,如果你想在滚动之间有时间延迟,那么
import Task
wait : Float -> msg -> Cmd msg
wait delay msgToCallWhenDone =
Task.perform (always msg) (Process.sleep delay)
会给你一个 Cmd
,它将在 delay
毫秒后调用你给它的任何消息。作为提示,您可能想为此介绍另一条信息。