Я делал игру в Техасский Холдем как часть оценки, и я размышлял над тем, как проверить 7 доступных карт и определить, существуют ли руки.
Единственный возможный метод, который я могу придумать, - это отсортировать карты по номерам, затем изучить каждую возможную группу из 5 карт и проверить, соответствуют ли они списку каждой возможной руки. Это займет много времени и будет возможно только для определения пар, так как костюм не имеет значения.
Каждая из карточек - это струны, состоящие из числа / a / j / q / k и масти (char)3
(которая делает небольшой символ пики).
Есть ли у кого-нибудь какие-либо предложения, формулы или ссылки, которые я мог бы использовать для создания системы анализа рук?
Пока не беспокойтесь о том, чтобы расставить руки друг против друга, это другой котелок рыбы.
Ответы:
Я думаю, что вы можете найти большинство покерных комбинаций, просто составив пару столов с указанием количества карт в руке каждого ранга и масти.
Другими словами, создайте карты карт массива (числа и A / J / Q / K) для подсчета карт этого ранга в вашей руке. Если у игрока есть пара или тройка в своем роде, в этом массиве будет элемент, равный 2 или 3, и т. Д. У него есть фулл-хаус, если есть один элемент, равный 2, и другой, равный 3, и прямой если в этом массиве пять последовательных элементов, равных 1
Точно так же вы можете составить аналогичный массив для подсчета карт каждой масти и использовать его для обнаружения флешей.
После того, как вы обнаружили присутствие определенной руки, довольно легко вернуться и найти конкретные карты в руке, чтобы выделить их в пользовательском интерфейсе или что вам нужно сделать.
В псевдокоде:
источник
Это немного сложно, потому что есть так много комбинаций. К счастью, у вас есть процессор, который может проверить множество комбинаций за очень короткое время.
Вам понадобится несколько разных стратегий для определения разных типов рук. К счастью, некоторые из различных типов могут перекрывать стратегии. Я бы искал по порядку по рангу руки.
2
,3
,6
,7
,8
Все простой подсчет. Используя список карт от туза до короля, просто поместите номер каждого значения в списке, увеличивая для каждой дополнительной найденной карты. Затем проверьте список на 4, если нет 4, у вас нет 4 в своем роде. Проверьте это на 3 с, если нет 3 с, у вас нет 3 в своем роде. Если у вас 3, проверьте на 2 (указав фулл хаус). И так далее...Для
1
,5
вы можете использовать тот же список и искать последовательности, где все карты имеют одну или несколько записей в списке для последовательности из 5 карт. Если у них тоже одинаковый костюм, это стрит-флеш.4
может иметь ту же настройку списка, но на этот раз вы рассчитываете костюм. Ищите числа 5 или выше.Наконец, у
9
вас есть самая высокая карта, и вам просто нужно посмотреть на последнее самое высокое значение из одного из ваших списков выше.Вы можете разорвать, как только вы нашли совпадение, если вы ищете в порядке. Хотя было бы тривиально продолжить поиск и найти все совпадения, если вы хотите предоставить всю эту информацию пользователю.
По сути, вы наполняете ведра. Затем проверяем ведра на комбинации. Проиллюстрировать:
Начиная с массива, с ведром для каждой карты, перебирайте карты и подсчитывайте количество экземпляров каждой карты. Затем вы можете легко перебрать массив и проверить наличие определенных комбинаций. В этом примере ясно, что существует 4 вида, потому что в одном из блоков есть 4 элемента.
источник
Я наткнулся на этот алгоритм один раз. Он умножает простые числа, чтобы определить руки, и это очень интересное чтение. Кактус Кев покерная комбинация
источник
В дополнение к отличным ответам на этот вопрос уже получен, я подумал, что было бы полезно предложить один из самых простых способов сравнения рук после того, как базовый метод классификации на месте. Прежде всего, вы захотите пометить руки своим классом , как подсказывают многочисленные ответы - большинство ваших сравнений «рука X лучше руки Y?» тогда можно сделать это, просто сравнив классы двух рук и увидев, какой класс лучше. В остальном вам действительно нужно сравнивать по карточкам, и оказывается, что немного больше работы в классификации упростит эту задачу.
В качестве базового случая рассмотрим ситуацию, когда обе руки являются руками «старшей карты»; в этом случае вы сначала сравниваете две старшие карты, затем (если они совпадают) следующие две карты и т. д. Если вы предполагаете, что каждая входная рука отсортирована от самой верхней до самой низкой карты, такой подход приводит к коду, который выглядит следующим образом: это:
Теперь, хорошая новость: оказывается, что этот лексикографический порядок , соответствующим образом подправленный, работает для сравнения двух рук в любомклассов, пока их класс одинаков. Например, поскольку способ сравнения пар состоит в том, чтобы сначала сравнить пары, а затем три другие карты, вы можете отсортировать свою руку, чтобы поставить пару первой (или даже одну карту пары первой!) И выполнить это же сравнение. (Так, например, такая рука, как A9772, будет сохранена как 77A92 или, что еще лучше, 7A927; рука A9972 будет сохранена как 9A729, и, сравнивая с приведенным выше кодом, вы начнете с расстановки 7 против 9 и обнаружите, что A9972 выиграл). Рука из двух пар будет храниться с наивысшей из этих двух пар, затем с более низкой, затем с кикером (например, A9977 будет хранить как 97A97); три вида будут храниться сначала с одной картой из трех, затем с кикерами, затем с другими картами (например, A7772 будет 7A277); полный дом будет храниться с одним из трех, а затем с одним из двух (например, 99777 будет храниться как 79779); и стриты и флеши могут храниться в «прямом лексикографическом» порядке, поскольку они сравниваются точно так же, как руки с высокими картами. Это приводит к простой внешней функции сравнения, которая работает для всех классов рук с уже заданной функцией:
Надеюсь, это поможет!
источник
Возможны некоторые распараллеливания с использованием подходящих представлений карт и переворота битов. Например, этот Java-код оценивает 7-карточные харды, возвращая целое число, которое можно использовать для сравнения двух рук. Он может быть адаптирован для сообщения о типе руки более удобным для пользователя способом. Основные идеи взяты из страницы Кактуса Кева, на которую есть ссылка в предыдущем ответе.
Если вас интересуют только возможные реализации для именования рук на разных языках, а не эффективность и ясность кода, вы также можете взглянуть на вызов Name в покере на codegolf.SE.
источник
Во-первых, вам нужно знать ранг и масть всех карт; тривиально, но необходимо.
Затем прокрутите эти 7 карт и создайте две гистограммы; один по рангу (используя массив с 13 индексами, все инициализируются в ноль и увеличиваются на 1, если и когда найдена карта в руке с таким рангом) и один по масти (используя массив из четырех элементов, построенных так же, как и для ранга) , Это линейные операции, и вы можете выполнять обе операции для каждой карты только для одного набора обходов.
Затем вы можете определить, существует ли какая-либо из следующих раздач, просто проверив каждую гистограмму на наличие сегментов, соответствующих критериям, и / или простого дополнительного теста:
Вы можете, естественно, объединить несколько из этих проверок:
По сути, если ответы на них дают какую-либо руку, установите полученное значение «сила руки» равным силе найденной руки, если значение еще не выше. Например, если у вас есть фулл-хаус, сила 7 из 9, то у вас также есть три типа, сила 4 и пара, сила 2.
Есть несколько ярлыков и быстрые выходы, но в целом это на самом деле не что дорого , чтобы просто запустить все проверки.
источник
Вы можете относительно легко делать покерные комбинации с простым итеративным подходом.
Для каждой карты, проверьте, есть ли один или два или три других с тем же лицом, чтобы проверить на пару или три / четыре вида.
Полные дома похожи. Или, если вы найдете пару и тройку не одинакового лица, пометьте аншлаг как найденный.
Для флешей проверьте каждый костюм, чтобы увидеть, есть ли пять одинаковых мастей.
Проверить прямо, даже если не отсортировано. Для каждой карты проверьте, есть ли одна более высокая, и повторяйте, пока пять последовательных карт не будут найдены или нет.
Флеш-рояль и стрит-флеш можно найти так же, как стриты. У флеш-роялей есть некоторые дополнительные условия, в которых карты с более низкой стоимостью можно игнорировать.
Да, такой подход неэффективен, но для большинства игр в покер это не имеет значения. Вы проверяете крошечную кучку игроков каждые полминуты или около того, а не проверяете тысячи раздач в секунду.
Существуют лучшие методы, но они могут занять больше времени для написания кода, и у вас, вероятно, есть более важные вещи, на которые можно потратить время / деньги, которые сделают лучшую игру с точки зрения игроков, помимо хитрости и эффективности алгоритма.
источник
простой способ найти пары, двойные пары, жетоны, фулл-хаусы, покер и т. д. заключается в следующем:
сравните каждую карту друг с другом во вложенном цикле, как этот:
Матчи пройдут следующим образом:
2 для пары
4 для двух пар
6 для тоака
8 для фуллхауса
12 для покера
чтобы оптимизировать скорость: нет необходимости запускать j-цикл до 5, его можно запустить до i-1. сравнение "i! = j" может быть удалено, тогда значения совпадения делятся пополам (1 = пара, 2 = 2 пары и т. д.)
источник