如何向这个榆树效果示例添加第二个骰子?
How do I add a second die to this elm effects example?
我是 Elm 的新手,一直在看下面的例子(注意这是在较新的 0.17 架构下,Action 现在是 Command):
http://elm-lang.org/examples/random
接下来的挑战是向示例中添加第二个骰子,这样单击按钮就会为每个骰子滚动一个新值。我的想法是更改模型以保存两个单独的值,每个值一个,ala
type alias Model =
{ dieFace1 : Int
, dieFace2 : Int
}
在我到达更新块之前,这一切正常。我不确定如何更新随机数生成器以创建两个值。这个功能让我有点困惑。
type Msg
= Roll
| NewFace Int Int
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
**(model, Random.generate NewFace (Random.int 1 6))** <-- not sure what to do here
NewFace newFace1 newFace2 ->
(Model newFace1 newFace2, Cmd.none)
Random.generate 函数的文档有点简单 -
generate : (a -> msg) -> Generator a -> Cmd msg
Create a command that will generate random values.
这是处理两个骰子的正确方法,还是有更好的方法?我是榆木小白,请大家多多关照:)
Random.int
是一个原始生成器,它给你一个随机整数。你需要一个能给你恰好两个随机整数的生成器。
可以从更原始的生成器构建随机数生成器来创建更复杂的生成器。幸运的是,Elm 有这样一个函数,Random.pair
可以让你为元组的每个部分指定你想要的两个生成器。
让我们把模具生成器拉到它自己的函数中,以避免重复我们自己:
dieGenerator : Random.Generator Int
dieGenerator =
Random.int 1 6
现在我们可以构建另一个生成器,为我们提供一对骰子的随机值:
diePairGenerator : Random.Generator (Int, Int)
diePairGenerator =
Random.pair dieGenerator dieGenerator
由于我们正在处理整数元组,让我们将 NewFace Int Int
的 Msg
定义更新为 NewFaces (Int, Int)
。这将使您的 Roll
处理程序变得干净整洁:
Roll ->
(model, Random.generate NewFaces diePairGenerator)
如果您想尝试超越这一点,请考虑允许滚动任意数量的骰子需要什么。采取从更原始的生成器构建复杂生成器的想法,并使用 Random
模块的文档作为指南。
一种方法是使用 batch
就像这里 https://gist.github.com/davidchase/40c27042bccfb00d786af0360b5bc3ea.
另一种方法是使用 Random.pair
或 Random.list
如果您需要超过 2 个:
import Html exposing (..)
import Html.App as Html
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Random
main : Program Never
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ dieFaces : (List Int)
}
--
get : Int -> List a -> Maybe a
get n xs = List.head (List.drop n xs)
-- http://rundis.github.io/blog/2016/elm_maybe.html
getOrOne : Int -> List Int -> Int
getOrOne n xs = Maybe.withDefault 1 (get n xs)
init : (Model, Cmd Msg)
init =
(Model [1, 1], Cmd.none)
-- UPDATE
type Msg
= Roll
| NewFace (List Int)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
(model, Random.generate NewFace (Random.list 2 (Random.int 1 6)))
NewFace newFace ->
(Model newFace, Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ img [ src ("/img/Alea_" ++ toString (getOrOne 0 model.dieFaces) ++ ".png")] []
, img [ src ("/img/Alea_" ++ toString (getOrOne 1 model.dieFaces) ++ ".png")] []
, button [ onClick Roll ] [ text "Roll" ]
]
还有一个https://github.com/jcollard/random-examples/blob/master/src/Dice.elm
除了@ChadGilbert 接受的答案中描述的更改外,我还必须更改 NewFaces
更新大小写(使用 elm 0.18.0
)。
NewFaces newFaces ->
let
(newFace1, newFace2) = newFaces
in
(Model newFace1 newFace2, Cmd.none)
我是 Elm 的新手,一直在看下面的例子(注意这是在较新的 0.17 架构下,Action 现在是 Command): http://elm-lang.org/examples/random
接下来的挑战是向示例中添加第二个骰子,这样单击按钮就会为每个骰子滚动一个新值。我的想法是更改模型以保存两个单独的值,每个值一个,ala
type alias Model =
{ dieFace1 : Int
, dieFace2 : Int
}
在我到达更新块之前,这一切正常。我不确定如何更新随机数生成器以创建两个值。这个功能让我有点困惑。
type Msg
= Roll
| NewFace Int Int
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
**(model, Random.generate NewFace (Random.int 1 6))** <-- not sure what to do here
NewFace newFace1 newFace2 ->
(Model newFace1 newFace2, Cmd.none)
Random.generate 函数的文档有点简单 -
generate : (a -> msg) -> Generator a -> Cmd msg
Create a command that will generate random values.
这是处理两个骰子的正确方法,还是有更好的方法?我是榆木小白,请大家多多关照:)
Random.int
是一个原始生成器,它给你一个随机整数。你需要一个能给你恰好两个随机整数的生成器。
可以从更原始的生成器构建随机数生成器来创建更复杂的生成器。幸运的是,Elm 有这样一个函数,Random.pair
可以让你为元组的每个部分指定你想要的两个生成器。
让我们把模具生成器拉到它自己的函数中,以避免重复我们自己:
dieGenerator : Random.Generator Int
dieGenerator =
Random.int 1 6
现在我们可以构建另一个生成器,为我们提供一对骰子的随机值:
diePairGenerator : Random.Generator (Int, Int)
diePairGenerator =
Random.pair dieGenerator dieGenerator
由于我们正在处理整数元组,让我们将 NewFace Int Int
的 Msg
定义更新为 NewFaces (Int, Int)
。这将使您的 Roll
处理程序变得干净整洁:
Roll ->
(model, Random.generate NewFaces diePairGenerator)
如果您想尝试超越这一点,请考虑允许滚动任意数量的骰子需要什么。采取从更原始的生成器构建复杂生成器的想法,并使用 Random
模块的文档作为指南。
一种方法是使用 batch
就像这里 https://gist.github.com/davidchase/40c27042bccfb00d786af0360b5bc3ea.
另一种方法是使用 Random.pair
或 Random.list
如果您需要超过 2 个:
import Html exposing (..)
import Html.App as Html
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Random
main : Program Never
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ dieFaces : (List Int)
}
--
get : Int -> List a -> Maybe a
get n xs = List.head (List.drop n xs)
-- http://rundis.github.io/blog/2016/elm_maybe.html
getOrOne : Int -> List Int -> Int
getOrOne n xs = Maybe.withDefault 1 (get n xs)
init : (Model, Cmd Msg)
init =
(Model [1, 1], Cmd.none)
-- UPDATE
type Msg
= Roll
| NewFace (List Int)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Roll ->
(model, Random.generate NewFace (Random.list 2 (Random.int 1 6)))
NewFace newFace ->
(Model newFace, Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ img [ src ("/img/Alea_" ++ toString (getOrOne 0 model.dieFaces) ++ ".png")] []
, img [ src ("/img/Alea_" ++ toString (getOrOne 1 model.dieFaces) ++ ".png")] []
, button [ onClick Roll ] [ text "Roll" ]
]
还有一个https://github.com/jcollard/random-examples/blob/master/src/Dice.elm
除了@ChadGilbert 接受的答案中描述的更改外,我还必须更改 NewFaces
更新大小写(使用 elm 0.18.0
)。
NewFaces newFaces ->
let
(newFace1, newFace2) = newFaces
in
(Model newFace1 newFace2, Cmd.none)