Pyth, 73 байта
eo_S+*-5l@\AN}SPMJ+NZSM.:+\AT5+-4l{eMJlM.gPkJ-sM*=T+`M}2Tc4"JQKA""hscd"=Zc
Это довольно ужасно. Разбор карт, сортировка значений ... Все занимает так много символов. Но подход интересен.
Попробуйте онлайн: демонстрация или тестовый набор
Объяснение:
Я генерирую все 52 карты, удаляю четыре карты ввода, генерирую счет для каждой карты (счет руки) и печатаю карту с максимальным счетом.
Счет немного странный. Если я сравню счет двух совершенно разных рук, он может выбрать не того победителя. Например, стрит побьет 4 туза. Но это работает, если первые 4 карты одинаковы в обеих руках. И мой вычисленный счет на самом деле не значение, а список значений:
- G: Сначала я группирую 5 карт по рангу и беру длины:
5h 5d 6c 5s Jd
->
[3, 1, 1]
- F: Затем я добавляю 4 минус количество различных наборов в этот список.
Flush
->
3
добавляется, not flush
->
2/1/0
добавляется.
- S: Добавить еще один номер.
0
если это не прямая, 4
если это прямая A2345
, или 5
если это более высокая прямая.
Эти списки из 4-7 номеров сортируются в порядке убывания и выбирается список с максимальным значением.
Почему это работает? Здесь вы видите возможные конфигурации для всех типов. Буква рядом с числами говорит вам, по какому правилу сгенерировано это число.
- Стрит-флеш:
[5S, 3F, 1G, 1G, 1G, 1G, 1G]
или[4S, 3F, 1G, 1G, 1G, 1G, 1G]
- Четыре вида:
[4G, 1G, 0F, 0S]
- Полный дом:
[3G, 2G, 1F, 0S]
или[3G, 2G, 0F, 0S]
- Румянец:
[3F, 1G, 1G, 1G, 1G, 1G, 0S]
- Straight:
[5S, 2F, 1G, 1G, 1G, 1G, 1G]
, [5S, 1F, 1G, 1G, 1G, 1G, 1G]
, [5S, 1G, 1G, 1G, 1G, 1G, 0F]
, [4S, 2F, 1G, 1G, 1G, 1G, 1G]
, [4S, 1F, 1G, 1G, 1G, 1G, 1G]
,[4S, 1G, 1G, 1G, 1G, 1G, 0F]
- Три вида:
[3G, 1G, 1G, 1F, 0S]
,[3G, 1G, 1G, 0F, 0S]
- Две пары
[2G, 2G, 2F, 1G, 0S]
, [2G, 2G, 1F, 1G, 0S]
,[2G, 2G, 1G, 0F, 0S]
- Одна пара:
[2G, 2F, 1G, 1G, 1G, 0S]
, [2G, 1G, 1G, 1G, 1F, 0S]
,[2G, 1G, 1G, 1G, 0F, 0S]
- Старшая карта:
[2F, 1G, 1G, 1G, 1G, 1G, 0S]
, [1F, 1G, 1G, 1G, 1G, 1G, 0S]
,[1G, 1G, 1G, 1G, 1G, 0S, 0F]
Pyth сравнивает списки поэлементно. Таким образом, очевидно, что стрит-флеш всегда побеждает четверых в своем роде. Большинство типичных правил покера очевидны с этими списками. Некоторые кажутся противоречивыми.
- Стрит выиграет у четверки или фулл-хауса: не проблема. Если у вас есть шанс получить четверку вида / фулл-хаус с картой ривера, то вы не можете достичь стрита одновременно (поскольку у вас уже есть 2 или 3 разных люкса в руке).
- Стрит победит против флеша. Если вы можете достичь флеша и стрита с речной картой, то вы также можете достичь стрит-флеша. И стрит-флеш имеет лучший результат, чем стрит и флеш.
- Одна пара
[2G, 2F, 1G, 1G, 1G, 0S]
выиграет против двух парных рук. Тоже нет проблем. Если вы получите две пары с речной картой, то у вас была хотя бы одна пара до ривера. Но это означает, что вы можете улучшить до трех в своем роде, что лучше. Таким образом, две пары на самом деле никогда не будут ответом.
- Старшая карта
[2F, 1G, 1G, 1G, 1G, 1G, 0S]
выиграет против одной пары рук. Если это лучший результат, который вы можете получить, до ривера у вас будет 3 карты одного набора и одна карта другого набора. Но затем вы можете выбрать карту с одним из этих двух наборов и с уже появившимся значением, и в итоге вы получите результат [2F, 2G, ...]
, что тоже лучше.
Таким образом, это выбирает правильный тип решения. Но как мне получить лучшую пару (из 4 возможных), как выбрать лучшую стрит, ...? Потому что два разных однопарных решения могут иметь одинаковый счет.
Это легко. Pyth гарантирует стабильную сортировку (при взятии максимума). Поэтому я просто генерирую карты в порядке 2h 2s 2c 2d 3h 3s ... Ad
. Таким образом, карта с самым высоким значением автоматически будет максимальной.
Детали реализации
=Zc
разбивает входную строку и сохраняет список карт в Z
.
=T+`M}2Tc4"JQKA"
генерирует список рангов ['2', ..., '10', 'J', 'Q', 'K', 'A']
и сохраняет их в T
. -sM*T..."hscd"Z
генерирует каждую комбинацию ранга с комплектами и удаляет карты Z
.
o...
упорядочивает эти оставшиеся карты по: lM.gPkJ
длине групп рангов, +-4l{eMJlM
добавляет 4 - длину (сюиты), +*-5l@\AN}SPMJ+NZSM.:+\AT5
добавляет 0/4/5 в зависимости от сюиты (сгенерируйте каждую подстроку длины 5 из «A» + T, проверьте, если рука один из них (требует сортировки руки и сортировки всех подмножеств), умножения на 5 (число «А» в карте), _S
сортирует список по убыванию.
e
выберите максимум и распечатайте.
JavaScript (ES6),
329324317312309 байтКак это работает
Для каждой оставшейся карты в колоде мы вычисляем счет руки
S
. Чем ниже оценка, тем лучше рука.Переменные, используемые для вычисления балла
F
: falsy, если рука флешc
: битмаск клубовd
: Битовая маска бриллиантовh
: битовая маска сердецs
: Пиковая маскаx = c | d
: битмаск клубов или бриллиантовy = h | s
: битовая маска сердец или пикиa
: битмаск всех комбинированных костюмовp = c & d | x & y | h & s
: пара битовых масок (1)t = c & d & y | h & s & x
: три в своем роде битовая маска (1)(1) Я написал эти формулы несколько лет назад и использовал их в нескольких покерных движках. Они работают. :-)
Другие формулы
c & d & h & s
: четвёртая битмаскa == 7681
: тест для специальной прямой "A, 2, 3, 4, 5" (0b1111000000001)((j = a / 31) & -j) == j
: тест для всех других стритовСчётная таблица
NB: Нам не нужно заботиться о двух парах, которые не могут быть нашим лучшим вариантом. (Если у нас уже есть одна пара, мы можем превратить ее в тройку. А если у нас уже есть две пары, мы можем превратить их в фулл-хаус.)
Контрольные примеры
Показать фрагмент кода
источник
JavaScript (ES6), 307
349Это довольно громоздко, и я не уверен, что это лучший подход.
Все еще немного пригодный для игры в гольф возможно.Меньше гольфа
Тест
источник