扑克牌建模问题

发布于 2024-11-18 21:09:27 字数 368 浏览 1 评论 0原文

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

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

我对 PokerHand 进行子类化的理由是,它将使检查获胜者手牌变得更加容易和更快,但我不确定这是否是一个好的工程......

是否有适合这里的设计模式?

谢谢!

I'm modeling a Poker game and I have a little design doubt:

I've a PokerHand, which is composed by 5 PokerCards. Should Straight, ThreeOfAKind, Poker, etc be subclasses of PokerHand? Or should they be symbols returned by a PokerHand method that computes what kind of hand it is?

My rationale for subclassing PokerHand is that it would make checking winner hands much easier and faster, but I'm not sure this is good engineering...

Is there any design pattern that would fit here?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

栖迟 2024-11-25 21:09:27

上学期,我必须用Java设计这样一个系统作为作业。虽然我们需要使用责任链模式来检查手牌,但我相当确定这是解决问题的一个糟糕方法,而且主要只是将模式插入作业中的一种方法。

如果我必须在没有责任链模式的情况下重做它,并使用更理智、更有凝聚力的策略列表,我会使用如下设计。

将有一个 Card 类,带有“颜色”(黑桃、梅花、方块、红心)和一个数字(均为枚举);一个 Hand 类,可容纳 5 张牌(如果您愿意,也可容纳 n 张牌);一个抽象 HandRank 类,它实现了 Comparable 接口,以及每种牌的子类(两种、三种、顺子等)每个都可以与另一个相比较(例如 StraightFlush 优于 TwoOfAKind);和一个基类AbstractHandAnalyzer。此 AbstractHandAnalyzer 将具有一个 Analyze(Hand) 方法,该方法将返回 HandRank 对象。

现在,您为每个 HandRank 子类创建一个 AbstractHandAnalyzer 子类。这些子类检查给定的手牌,如果手牌匹配,则返回 HandRank 实例(例如,如果 TwoOfAKindAnalyzer 发现您有两个国王,则返回 TwoOfAKindRank< /code> 告诉它找到了两个国王,并保存踢球以备稍后比较时需要)。

那么,要分析一手牌,您所要做的就是按降序排列一手牌分析器列表(因此您从同花顺开始),并运行该手牌上的每个分析器,直到有一个匹配且不返回 null

这里重要的部分是将扑克牌与队伍本身脱钩。对于大多数语言(但 Smalltalk 可能不是这种情况),如果构造一个 Hand 对象,则无法神奇地将其变形为另一个类,因此子类化 Hand 来限定根据您的对象实例化方案,排名可能会很困难,并且如果手牌可变(某些扑克变体允许交换牌),则排名几乎不可能。这种方法可以让您重用 Hand 并轻松实现各种 Hand 分析器。

Last semester, I had to design such a system in Java as a homework. While it was required we checked the hands using the chain of responsibility pattern, I'm fairly sure it was a bad approach to the problem and mostly just a way to plug the pattern into a homework.

If I had to redo it without the chain of responsibility pattern, and using a saner, more cohesive list of strategies, I would use a design like the following.

There would be a Card class, with a 'color' (spades, clubs, diamonds, hearts) and a number (both being enums); a Hand class, that holds 5 cards (or just n cards if you're into that); an abstract HandRank class that implements the Comparable<HandRank> interface, and subclasses for each kinds of hands (two of a kind, three of a kind, straight, etc) that are each comparable to another (such that StraightFlush is better than TwoOfAKind); and a base class AbstractHandAnalyzer. This AbstractHandAnalyzer would have a Analyze(Hand) method that would return a HandRank object.

Now, you make one subclass of AbstractHandAnalyzer per HandRank subclass. Those subclasses check a given hand and return a HandRank instance if the hand matches (for instance, if TwoOfAKindAnalyzer finds that you have two kings, it returns a TwoOfAKindRank that tells it found two kings, and saves the kicker in case it needs it during a comparison later).

All you have to do to analyze a hand, then, is to have a list of hand analyzers in descendant order (so you start with the straight flush), and run each analyzer on the hand until one matches by not returning null.

The important part here is to decouple the poker hands from the ranks themselves. With most languages (it might not be the case with Smalltalk though), if you construct a Hand object, you cannot magically morph it into another class, so subclassing Hand to qualify the ranks can be hard depending on your object instantiation scheme, and can be made next-to-impossible if the hand is mutable (some poker variants allow to swap cards). This approach lets you reuse Hand and easily implement various analyzers for hands.

荒岛晴空 2024-11-25 21:09:27

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

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

  • Type - 表示组合的枚举。
  • Player - 引用玩家。
  • Cards - 涉及卡片的引用数组。

然后实现比较逻辑,以便可以比较任意两个组合:首先按 Type 比较,然后按 Cards (对于最高的卡片)。

PokerHand should have a method: GetCombination that returns enum or object. Hand is hand, and if player has Straigt it doesn't add any new behavior or state. So combination is calculable from cards.

Edit: I would create class Combination with these properties:

  • Type - enum that represents combination.
  • Player - ref to player.
  • Cards - array of ref to involved cards.

Then implement comparison logic, so that any two combinations could be compared: first by Type then by Cards (for highest card).

琴流音 2024-11-25 21:09:27

我可能会将一手扑克牌视为一组(大概是 5 张)牌。然后,为了检查它是什么样的手牌,我将创建一个 CalculateValue() 方法,该方法返回 1(表示对)、2(表示两对)、3(表示三对)等。该值可以是在构造手时进行计算,然后在需要时简单地重复使用。

祝你好运!

I would probably work with a poker hand as a set (5 presumably) of cards. Then, to check what kind of hand it is, I would create a CalculateValue() method that returns 1 for pair, 2 for two pairs, 3 for three of a kind, etc. This value could be computed when the hand is constructed, then simply reused whenever it is needed.

Good luck!

高速公鹿 2024-11-25 21:09:27

我一直在思考:

我的推理是所有牌都可以分类为 HighCardPairTwoPairsThreeOfAKind< /code>、StraightFlushFullHouseFourOfAKind同花顺。它们都是手的种类(或类),而Hand只是一个抽象类。

所有这些子类只需要重写 <>,然后询问一只手是否比另一只手更好就变得和执行 aHand 一样简单。 anotherHand,看起来非常自然。

在现实生活中,我们会拿双手进行比较,首先查看它们的种类(类别),然后(并且仅在必要时)查看它们的牌的价值。因此,使用这种方法, <> 的行为将与此完全相同:检查类是否不同,如果不同,我们会自动获得答案。如果不是,我们会递归地检查哪一张拥有最好的牌。

I've been thinking about it:

My reasoning is that all hands can be categorized under HighCard, Pair, TwoPairs, ThreeOfAKind, Straight, Flush, FullHouse, FourOfAKind and StraightFlush. All of them are kinds (or classes) of hands, and Hand is just an abstract class.

All these subclasses just need to override < and >, then asking a hand if it's better than another one becomes just as simple as doing aHand < anotherHand, which looks very natural.

In real life, we would take both hands and compare them by looking first at their kind (class), then (and only if necessary) at the value of their cards. So with this approach, < and > would behave exactly as this: check whether the classes are different, in case they are we get the answer automatically. In case they aren't, we recursively check which one has the best cards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文