Вопрос по моделированию рук в покере - PullRequest
0 голосов
/ 06 июля 2011

Я моделирую игру в покер, и у меня есть небольшое сомнение в дизайне:

У меня есть PokerHand, который состоит из 5 PokerCard с. Должны ли Straight, ThreeOfAKind, Poker и т. Д. Быть подклассами PokerHand? Или они должны быть символами, возвращенными методом PokerHand, который вычисляет, какая это рука?

Мое обоснование для подкласса PokerHand состоит в том, что это сделало бы проверку рук победителя намного проще и быстрее, но я не уверен, что это хорошая техника ...

Есть какой-нибудь шаблон дизайна, который бы подходил здесь?

спасибо!

Ответы [ 4 ]

3 голосов
/ 06 июля 2011

В прошлом семестре я должен был разработать такую ​​систему на Java как домашнее задание.Хотя требовалось, чтобы мы проверили руки, используя схему цепочки ответственности, я вполне уверен, что это был плохой подход к проблеме и в основном просто способ вставить шаблон в домашнюю работу.

Если бы у меня былочтобы переделать его без схемы цепочки ответственности и с использованием более разумного, более сплоченного списка стратегий, я бы использовал такой дизайн:

Был бы класс Card с цветом(пики, трефы, бриллианты, червы) и число (оба enum с);класс Hand, который вмещает 5 карт (или просто n карт, если вам это нравится);абстрактный класс HandRank, который реализует интерфейс Comparable<HandRank>, и подклассы для каждого вида рук (два вида, три вида, прямые и т. д.), каждый из которых сопоставим с другим (так что StraightFlush лучшечем TwoOfAKind);и базовый класс AbstractHandAnalyzer.Этот AbstractHandAnalyzer будет иметь метод Analyze(Hand), который будет возвращать объект HandRank.

Теперь вы создаете один подкласс из AbstractHandAnalyzer на HandRank подкласс.Эти подклассы проверяют данную руку и возвращают экземпляр HandRank, если рука совпадает (например, если TwoOfAKindAnalyzer находит, что у вас есть два короля, он возвращает TwoOfAKindRank, который сообщает, что он нашел двух королей, и сохраняет кикера весли это понадобится во время сравнения позже).

Все, что вам нужно сделать, чтобы проанализировать руку, - это иметь список анализаторов рук в порядке убывания (поэтому вы начинаете со стрит-флеша), изапускайте каждый анализатор на руке до тех пор, пока один из них не совпадет, не возвращая null.

Важной частью здесь является отсоединение покерных рук от самих рангов.В большинстве языков (хотя это может и не быть в случае Smalltalk), если вы создаете объект Hand, вы не можете волшебным образом превратить его в другой класс, поэтому создание подклассов Hand для определения рангов может быть затруднено в зависимости от того, какой экземпляр вы создали.схема, и может быть сделана практически невозможной, если рука изменчива (некоторые варианты покера позволяют менять карты).Такой подход позволяет повторно использовать Hand и легко применять различные анализаторы для рук.

2 голосов
/ 06 июля 2011

PokerHand должен иметь метод: GetCombination, который возвращает enum или object. Рука - это рука, и если у игрока есть Straigt, он не добавляет никакого нового поведения или состояния. Таким образом, комбинация вычисляется из карт.

Редактировать: Я бы создал класс Combination со следующими свойствами:

  • Type - перечисление, представляющее комбинацию.
  • Player - ссылка на игрока.
  • Cards - массив ссылок на вовлеченные карты.

Затем реализуйте логику сравнения, чтобы можно было сравнивать любые две комбинации: сначала на Type, затем на Cards (для старшей карты).

0 голосов
/ 06 июля 2011

Я думал об этом:

Я считаю, что все руки могут быть классифицированы как HighCard, Pair, TwoPairs, ThreeOfAKind, Straight, FlushFullHouse, FourOfAKind и StraightFlush.Все они являются видами (или классами) рук, а Hand является просто абстрактным классом.

Все эти подклассы просто должны переопределить < и >, тогдаспрашивать руку, лучше ли она, чем другая, становится так же просто, как и делать aHand < anotherHand, что выглядит очень естественно.

В реальной жизни мы брали бы обе руки и сравнивали их, сначала глядя на их вид (класс), то (и только при необходимости) по стоимости их карточек.Таким образом, при таком подходе < и > будут вести себя именно так: проверьте, не отличаются ли классы, в случае их получения мы получим ответ автоматически.В противном случае мы рекурсивно проверяем, какая из них имеет лучшие карты.

0 голосов
/ 06 июля 2011

Я бы, вероятно, работал с покерной комбинацией в виде набора (предположительно, 5) карт. Затем, чтобы проверить, что это за рука, я бы создал метод CalculateValue(), который возвращает 1 для пары, 2 для двух пар, 3 для трех видов и т. Д. Это значение может быть вычислено при построении руки, затем просто повторно использовать всякий раз, когда это необходимо.

Удачи!

...