【问题标题】:change of conditions in recursive function递归函数中的条件变化
【发布时间】:2014-09-13 10:40:48
【问题描述】:

首先这是一个任务,所以我不想要一个完整的解决方案:)

我要计算纸牌游戏二十一点中一副牌的价值。

规则是所有 A 是 1 或 11。

假设我的手牌是:(Ace, 5),我的手牌现在是 16。下一张牌是 6,我的手牌现在是 (Ace, 5,6) 22,但我之前已经计算的 A 现在必须变为一所以我的手是12。

我的 Hand 数据类型由

递归定义
data Hand = Empty | Add Card Empty

所以用固定值计算一手牌是由

完成的
valueOfHand (Add c h) = cardValue c + valueOfHand h

改变之前出现的值的模式是什么?

【问题讨论】:

  • 你为什么不直接使用type Hand = [Card]?这样可以更容易地以惯用的方式解决这个问题。
  • @leftaroundabout 我不知道它在提供的文件中是这样定义的 :)
  • 我不知道什么是“所有 A 都是 1 独占或 11”。应该是这个意思。
  • 你的Hand 类型本质上是一个列表。我会查看List([]) 的Monad 实例,并使用它的不确定性来检查你的A 的所有可能读数,然后选择你手牌的价值,不管是什么(会有不止一个,尤其是如果您以某种方式设法绘制了不止一张 A)。
  • @BartekBanachewicz 可以说我手里有两张 A 都必须是 1 或 11 他们不能有单独的值

标签: haskell recursion


【解决方案1】:

我不确定你的班级是否已经涵盖了 list monad,但我认为这是解决这个问题的最自然的方法。因此,与其让cardValue 返回一个简单的值,不如返回一个不确定的值,列出卡片可能具有的所有可能值,即

cardValue :: Card -> [Int]
cardValue Ace = [1, 11]
cardValue Two = [2]
...

valueOfHand 将有两个部分:一个计算所有可能手牌值的列表,另一个选择最好的合法手牌。

让我知道这是否足以让您解决它或者您是否需要更多提示。

【讨论】:

    【解决方案2】:

    如果,正如您在 cmets 中指出的那样,Aces 每手牌可能只有一个值(因此三个 Aces 的手牌是 3 或 33),那么定义您的 valueOfHand :: Hand -> Integer 函数是有意义的以一种首先汇总非Ace 卡然后处理Aces 的方式。

    我希望这样的功能将基于以下内容:

    valueOfHand Empty = 0

    valueOfHand h = valueOfAces (filter (\c -> c == Ace) h) (filter (\c -> c /= Ace) h)

    对于某些功能valueOfAces :: Hand -> Hand -> Integer

    【讨论】:

    • 你应该写valueOfAces (filter (\c -> c == Ace) h) (filter (\c -> c /= Ace) h)而不是uncurry valueOfAces (span (==Ace) h)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多