如何使用Elm自定义类型对5个骰子值进行建模



我正在尝试用Elm制作一个简单的骰子游戏。我会有一个";骰子杯";其包含5、6边骰子。当你";滚动";骰子,你得到5个随机骰子值。最后;1〃;值被认为是";"野生";,并且可以用来代替任何其它的管芯值。

因此,目前,我已经使用Random.generate命令来生成值为1和6:之间的5个IntList

Roll ->
( model
, Random.generate NewRoll (Random.list 5 (Random.int 1 6))
)

所以,我可以把我的杯子做成这样:type alias Cup = List Int

但我认为,在我的数据周围添加更多的形式化可能会很有价值。尤其是在阅读了这篇文章之后,我觉得我应该更像这样建模我的数据:

type alias Cup = List Die
type Die
= One
| Two
| Three
| Four
| Five
| Six

不过,我在为一些事情而挣扎。首先,虽然这种Die类型感觉像是一种更明确、更准确的Cup建模方式,但我很难确定如何将这些类型变量值与实际的整数值相关联。当我使用我的随机数生成器时,它会产生整数。

我该如何将它们与我的命名类型进行协调?即使我可以,我该如何走向另一个方向?我最终需要在我的杯子上执行一些逻辑;"好";滚动是,这将涉及评估哪些价值观比其他价值观更大,以及我拥有每个价值观中的多少。

我的倾向是,应该有一个与每个变量相关的整数值来形成数据构造函数One Int,但这是不对的。这意味着任何整数都可以与变量One相关联,这不是我想要的。我只想要整数:1

我的第二个倾向是,我的Die类型使用类似Die int的类型参数,而忽略变体,而是将die值直接与Die类型关联。这将允许用Die类型来分配其他类型的数据,比如表示骰子是否为野生的Bool。然而,我突然想到,事情并不是这样运作的。类型参数似乎是用来为类型Die的变体提供不明确的数据类型的。我无法制作Die Int类型的单机版。

所以我不确定我会从这里走向何方。自定义类型感觉像是我的数据建模的答案,但在这一点上,我想知道我是否真的应该使用记录?

我还想知道是否有某种方法可以将一直倾斜到我的类型变体中。有可能随机生成这些类型的变体吗?但是,我该如何将这些变量值与逻辑进行比较呢?

下面的怎么样?

type Die
= One
| Two
| Three
| Four
| Five
| Six

type Cup
= Cup Die Die Die Die Die

die : Random.Generator Die
die =
Random.uniform One [ Two, Three, Four, Five, Six ]

cup : Random.Generator Cup
cup =
Random.map5 Cup die die die die die

toInt : Die -> Int
toInt d =
case d of
One ->
1
Two ->
2
Three ->
3
Four ->
4
Five ->
5
Six ->
6

我会更进一步,考虑您想要编码一个可以用作任何值的wild-die。一些假设:

  • 文字值为2到6。1是一个占位符,可以采用任何文字值
  • 掷骰子中产生的狂野骰子在稍后分配之前不计入任何值
  • 您需要意识到,在为野生骰子指定值后,它就是野生骰子。(即分配后不会忘记野生状态(
  • 一旦分配,野死就不能再分配

所以让我们先使用我们的文字值:

type LiteralValue
= Two
| Three
| Four
| Five
| Six

掷骰子是一个文字值,或者是一个可能被分配或不被分配文字值的野生骰子。

type Die
= Literal LiteralValue
| Wild (Maybe LiteralValue)

轧制时,模具是的六个值之一

generator : Random.Generator Die
generator =
Random.uniform
( Wild Nothing ) -- Wild is always rolled unassigned
[ Literal Two
, Literal Three
, Literal Four
, Literal Five
, Literal Six
]

您可以稍后为未分配的野生骰子指定一个值。字面骰子和指定的野生骰子不受影响。

assign : LiteralValue -> Die -> Die
assign value die =
case die of
Wild Nothing ->
Wild (Just value)
_ ->
die

最新更新