You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elm中如何为Model内的两个骰子分配不同随机值?

Fixing the Dual Dice Randomization Issue in Elm

Hey there! Let's get those two dice rolling different numbers instead of matching every time. I'll walk you through the problem and the solution step by step.

What's Causing the Same Value for Both Dice?

Looking at your code, the issue is in how you're generating and applying random numbers:

  • When you click "Roll", you're only generating one random number with Random.generate NewFace (Random.int 1 6)
  • Then in the NewFace branch, you set both dieFace1 and dieFace2 to that single value: ( Model newFace newFace, Cmd.none )

Naturally, both dice end up identical! We need to generate two independent random numbers and assign each to its own die face.

Step-by-Step Fix

  1. Update the Msg Type
    We need a message that can carry two random numbers instead of one. Change your Msg definition to:

    type Msg = Roll | NewFaces (Int, Int)
    
  2. Generate a Pair of Random Numbers
    In the Roll branch of update, use Random.pair to create two independent 1-6 random values at once:

    Roll ->
        ( model, Random.generate NewFaces (Random.pair (Random.int 1 6) (Random.int 1 6)) )
    
  3. Assign Each Random Number to Its Die
    Modify the NewFaces branch to unpack the tuple and assign each value to the correct die face:

    NewFaces (face1, face2) ->
        ( Model face1 face2, Cmd.none )
    

Full Modified Code

Here's the complete code with all changes applied (I've added comments where modifications were made):

import Html exposing (..)
import Html.Attributes
import Html.Events exposing (..)
import List
import Random
import Svg exposing (..)
import Svg.Attributes exposing (..)

main = Html.program { init = init , view = view , update = update , subscriptions = subscriptions }

-- MODEL
type alias Model = { dieFace1 : Int , dieFace2: Int }

init : ( Model, Cmd Msg )
init = ( Model 2 5, Cmd.none )

-- UPDATE
-- Modified Msg type to carry a pair of integers
type Msg = Roll | NewFaces (Int, Int)

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model = 
    case msg of
        Roll ->
            -- Generate a pair of random numbers instead of one
            ( model, Random.generate NewFaces (Random.pair (Random.int 1 6) (Random.int 1 6)) )

        NewFaces (face1, face2) ->
            -- Assign each random number to its respective die face
            ( Model face1 face2, Cmd.none )

-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model = Sub.none

-- VIEW
view : Model -> Html Msg
view model = 
    div []
        [ h1 [] [ Html.text (toString (model.dieFace1 + model.dieFace2)) ]
        , svg [ width "120", height "120", viewBox "0 0 120 120", fill "white", stroke "black", strokeWidth "3", Html.Attributes.style [ ( "padding-left", "20px" ) ] ]
            (List.append [ rect [ x "1", y "1", width "100", height "100", rx "25", ry "25" ] [] ] (svgCirclesForDieFace model.dieFace1) )
        , svg [ width "120", height "120", viewBox "0 0 120 120", fill "white", stroke "black", strokeWidth "3", Html.Attributes.style [ ( "padding-left", "20px" ) ] ]
            (List.append [ rect [ x "1", y "1", width "100", height "100", rx "25", ry "25" ] [] ] (svgCirclesForDieFace model.dieFace2) )
        , br [] []
        , button [ onClick Roll ] [ Html.text "Roll" ]
        ]

svgCirclesForDieFace : Int -> List (Svg Msg)
svgCirclesForDieFace dieFace = 
    case dieFace of
        1 ->
            [ circle [ cx "50", cy "50", r "10", fill "black" ] [] ]

        2 ->
            [ circle [ cx "25", cy "25", r "10", fill "black" ] []
            , circle [ cx "75", cy "75", r "10", fill "black" ] []
            ]

        3 ->
            [ circle [ cx "25", cy "25", r "10", fill "black" ] []
            , circle [ cx "50", cy "50", r "10", fill "black" ] []
            , circle [ cx "75", cy "75", r "10", fill "black" ] []
            ]

        4 ->
            [ circle [ cx "25", cy "25", r "10", fill "black" ] []
            , circle [ cx "75", cy "25", r "10", fill "black" ] []
            , circle [ cx "25", cy "75", r "10", fill "black" ] []
            , circle [ cx "75", cy "75", r "10", fill "black" ] []
            ]

        5 ->
            [ circle [ cx "25", cy "25", r "10", fill "black" ] []
            , circle [ cx "75", cy "25", r "10", fill "black" ] []
            , circle [ cx "25", cy "75", r "10", fill "black" ] []
            , circle [ cx "75", cy "75", r "10", fill "black" ] []
            , circle [ cx "50", cy "50", r "10", fill "black" ] []
            ]

        6 ->
            [ circle [ cx "25", cy "20", r "10", fill "black" ] []
            , circle [ cx "25", cy "50", r "10", fill "black" ] []
            , circle [ cx "25", cy "80", r "10", fill "black" ] []
            , circle [ cx "75", cy "20", r "10", fill "black" ] []
            , circle [ cx "75", cy "50", r "10", fill "black" ] []
            , circle [ cx "75", cy "80", r "10", fill "black" ] []
            ]

        _ ->
            [ circle [ cx "50", cy "50", r "50", fill "red", stroke "none" ] [] ]

How This Works

  • Random.pair creates a generator that produces two independent random values (each between 1 and 6 in this case)
  • The NewFaces message carries both values as a tuple
  • We then unpack the tuple and assign each value to its corresponding die face in the model

Now when you click "Roll", each dice will get its own random number—they might still match occasionally (hey, randomness!) but that's just chance, not a bug.

内容的提问来源于stack exchange,提问作者aThink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:52:39