【问题标题】:Elm Guide Dice Exercise榆树指导骰子练习
【发布时间】:2021-07-21 13:05:35
【问题描述】:

我正在从 Random Section 进行 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" ] []
      ]
      
    _ ->
      []

【问题讨论】:

    标签: functional-programming elm


    【解决方案1】:

    诀窍主要在于要求运行时向您发送消息。

    你可以尝试的第一件事就是改变

      NewFace (newFace, newFace2) ->
          ( Model newFace newFace2
          , Cmd.none
          )
    

      NewFace (newFace, newFace2) ->
          ( Model newFace newFace2
          , Random.generate NewFace randomPair
          )
    

    这有一个问题是永远不会停止,让你的程序永远旋转......

    因此您需要跟踪一些停止条件。也许在您的模型中添加一个字段来跟踪它已经滚动了多少次?然后根据该字段在Random.generateCmd.none 之间切换。


    最后,如果你想要滚动之间的时间延迟,那么

    import Task
    
    
    wait : Float -> msg -> Cmd msg
    wait delay msgToCallWhenDone =
      Task.perform (always msg) (Process.sleep delay)
    

    会给你一个Cmd,它会在delay毫秒后调用你给它的任何消息。作为提示,您可能想为此介绍另一个味精。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多