如何使用Elm自定义类型建模5个骰子的点数?
Elm 骰子游戏建模与随机生成解决方案
1. 直接生成 Die 类型的随机值
不用先生成整数再转换,直接定义一个Random.Generator Die,可以直接在Random.generate里使用:
import Random type Die = One | Two | Three | Four | Five | Six dieGenerator : Random.Generator Die dieGenerator = Random.int 1 6 |> Random.map intToDie intToDie : Int -> Die intToDie n = case n of 1 -> One 2 -> Two 3 -> Three 4 -> Four 5 -> Five 6 -> Six -- 由于生成的是1-6范围的整数,默认分支不会触发,也可加Debug.crash强化类型安全
对应的Roll消息处理可以改成:
Roll -> ( model , Random.generate NewRoll (Random.list 5 dieGenerator) )
2. Die与整数的类型安全转换
写反向转换函数,满足后续数值比较和计数需求:
dieToInt : Die -> Int dieToInt die = case die of One -> 1 Two -> 2 Three -> 3 Four -> 4 Five -> 5 Six -> 6
如果需要处理外部非1-6的整数输入,可将intToDie改为返回Maybe Die,避免无效值:
intToDie : Int -> Maybe Die intToDie n = case n of 1 -> Just One 2 -> Just Two 3 -> Just Three 4 -> Just Four 5 -> Just Five 6 -> Just Six _ -> Nothing
3. 百搭逻辑处理
单独写判断函数,无需修改Die类型结构:
isWild : Die -> Bool isWild die = die == One
后续计算牌型时,可通过该函数将One纳入对应点数的统计逻辑。
4. 自定义类型 vs 记录类型
- 仅表示骰子点数时,自定义枚举类型更优:能杜绝无效值(比如Int类型可能出现的0或7),类型检查更严格。
- 若需给骰子附加状态(如是否锁定、是否高亮),可结合记录类型:
type alias DieWithState = { face : Die , isLocked : Bool } type alias Cup = List DieWithState
5. 变体的逻辑比较
- 直接用
==判断两个Die变体是否相等; - 按点数大小比较时,借助
dieToInt转换为整数后操作:
compareDice : Die -> Die -> Order compareDice a b = compare (dieToInt a) (dieToInt b)
示例:对骰盅内的骰子按点数排序
sortedCup : Cup -> Cup sortedCup = List.sortWith compareDice
内容的提问来源于stack exchange,提问作者Esten
相关产品推荐
相关产品推荐

