【发布时间】:2011-10-22 13:04:23
【问题描述】:
对于那些不知道什么是 5 张扑克顺子的人:http://en.wikipedia.org/wiki/List_of_poker_hands#Straight
我正在用 Scala 编写一个小型扑克模拟器来帮助我学习该语言,并且我创建了一个 Hand 类,其中包含 5 张有序的卡。每张卡片都有一个Rank和Suit,两者都定义为Enumerations。 Hand 类具有评估手牌等级的方法,其中一个检查手牌是否包含顺子(我们暂时可以忽略同花顺)。我知道有一些很好的算法可以确定直线,但我想看看我是否可以用 Scala 的模式匹配设计一些东西,所以我想出了以下内容:
def isStraight() = {
def matchesStraight(ranks: List[Rank.Value]): Boolean = ranks match {
case head :: Nil => true
case head :: tail if (Rank(head.id + 1) == tail.head) => matchesStraight(tail)
case _ => false
}
matchesStraight(cards.map(_.rank).toList)
}
这很好用并且可读性很好,但我想知道是否有任何方法可以摆脱那个if。我想像下面这样,虽然我不能让它工作:
private def isStraight() = {
def matchesStraight(ranks: List[Rank.Value]): Boolean = ranks match {
case head :: Nil => true
case head :: next(head.id + 1) :: tail => matchesStraight(next :: tail)
case _ => false
}
matchesStraight(cards.map(_.rank).toList)
}
有什么想法吗?另外,作为一个附带问题,关于内部 matchesStraight 定义的一般意见是什么?这应该是私人的还是以不同的方式完成?
【问题讨论】:
-
您可以定义自己的提取器,它看起来像您想要的任何东西,也可以完成您需要的任何东西。
-
@agilesteel 我考虑过,但是(1)我还没有找到一种方法来仍然引用递归调用的匹配值,并且(2)我相信我需要创建一个提取器'+' 也一样吗?
-
如果枚举自动定义了
unapply方法,你可以写成case head :: (next @ Rank(nextRank)) :: tail if nextRank == head.id + 1,但它们没有。 -
感谢 Alexey,至少解决了问题 (1) ...
标签: scala pattern-matching idioms