扑克手建模问题

时间:2011-07-06 14:37:53

标签: design-patterns smalltalk

我正在为扑克游戏建模,我有一点设计疑问:

我有一个PokerHand,由5 PokerCard组成。 StraightThreeOfAKindPoker等应该是PokerHand的子类吗?或者它们应该是PokerHand方法返回的符号,它计算它是什么样的手?

我对PokerHand进行子类化的理由是,它会让检查胜利者的手更容易,更快,但我不确定这是好工程......

这里有适合的设计模式吗?

谢谢!

4 个答案:

答案 0 :(得分:3)

上个学期,我不得不用Java作为家庭作业设计这样一个系统。虽然需要我们使用责任链模式来检查手,我很确定这是一个解决问题的方法,而且大多只是将模式插入作业的方法。

如果我不得不在没有责任链模式的情况下重做它,并使用更健全,更有凝聚力的策略列表,我会使用如下设计。

会有Card类,有'颜色'(黑桃,棍棒,钻石,心形)和数字(都是enum s);一个Hand课程,可以持有5张卡片(或者只有n张卡片;实现HandRank接口的抽象Comparable<HandRank>类,以及每种类型的手(两种,三种,直,等)的子类,每种都可以与另一种相媲美(这样{ {1}}优于StraightFlush);和基类TwoOfAKind。这个AbstractHandAnalyzer会有AbstractHandAnalyzer方法返回Analyze(Hand)个对象。

现在,您为HandRank每个AbstractHandAnalyzer子类创建一个子类。如果手匹配,那些子类检查给定的手并返回HandRank实例(例如,如果HandRank发现你有两个国王,它会返回TwoOfAKindAnalyzer,告诉它找到两个国王,并在以后的比较中保存踢球者以防万一。)

分析一只手的所有工作就是按顺序排列一个手动分析器列表(所以你从同花顺开始),然后在手上运行每个分析器直到一个匹配,不再返回{ {1}}。

这里的重要部分是将扑克牌与队伍本身分开。对于大多数语言(尽管Smalltalk可能不是这种情况),如果你构造一个TwoOfAKindRank对象,你就不能神奇地将它变形为另一个类,所以继承null来限定等级可能很难取决于在你的对象实例化方案中,如果手是可变的(一些扑克变种允许交换卡),可以使其成为接下来的不可能。这种方法允许您重用Hand并轻松实现各种分析器。

答案 1 :(得分:2)

PokerHand应该有一个方法:GetCombination,返回enumobject。手是手,如果玩家有Straigt,它不会添加任何新的行为或状态。所以组合可以通过卡片来计算。

编辑:我会创建具有以下属性的类Combination

  • Type - 代表组合的枚举。
  • Player - 参考播放器。
  • Cards - 参与卡片的参考数组。

然后实施比较逻辑,以便可以比较任何两种组合:首先是Type,然后是Cards(最高卡)。

答案 2 :(得分:0)

我可能会用扑克牌作为一组(大概是5张)牌。然后,为了检查它是什么样的手,我会创建一个CalculateValue()方法,返回1对,2对2对,3对3,等等。当手是构建,然后只需在需要时重复使用。

祝你好运!

答案 3 :(得分:0)

我一直在想它:

我的理由是,所有人都可以归类为HighCardPairTwoPairsThreeOfAKindStraightFlush,{ {1}},FullHouseFourOfAKind。所有这些都是(或类)的手,StraightFlush只是一个抽象类。

所有这些子类只需覆盖Hand<,然后询问一只手是否比另一只更好,就像做>一样简单,看起来非常自然。 / p>

在现实生活中,我们会先拿双手并比较它们,先看看他们的种类(班级),然后(并且只在必要时)查看他们卡片的价值。因此,使用此方法,aHand < anotherHand<的行为与此完全相同:检查类是否不同,以防我们自动获得答案。如果不是,我们递归检查哪一张卡最好。