Hold'em або Fold'em?


17

Ваш друг запросив вас в останню хвилину в покер на високі ставки, і, як комп'ютер, ви вирішили використати свої навички, щоб отримати перевагу в грі. Ваше завдання буде, дано 2 cards(ваша рука) та 0, 3, 4 or 5 cards(роздані картки), ви повинні вирішити, якою найкращою може бути рука. Якщо всі 7 карток подано як аргументи, відповідь досить чітка. Якщо менше, проблема стає більш складною. Однак цього недостатньо для того, щоб дати вам перевагу, яку ви шукаєте, ви також повинні обчислити найкращу руку з решти карт, щоб зрозуміти, що можуть мати і ваші опоненти.


Оновлення Hold'em

Якщо ви не знаєте про hold'em, кожен гравець у грі починається з 2 карт як "рука". Протягом 3-х поворотів виявляються додаткові картки, які можна ділити між усіма гравцями. Перша черга, 3 картки розкриваються. Другий, ще 1 і втретє розкривається підсумкова карта. Дві картки, подані першими, представляють вашу руку, тоді як остання представляє 0, 3, 4 або 5 карт, що даються послідовними поворотами.


Можливі номери:

[2,3,4,5,6,7,8,9,T(10),J,Q,K,A]

Можливі костюми:

[S,C,H,D]

Повна колода:

[2S,3S,4S,5S,6S,7S,8S,9S,TS,JS,QS,KS,AS, # Spades.
 2C,3C,4C,5C,6C,7C,8C,9C,TC,JC,QC,KC,AC, # Clubs.
 2H,3H,4H,5H,6H,7H,8H,9H,TH,JH,QH,KH,AH, # Hearts.
 2D,3D,4D,5D,6D,7D,8D,9D,TD,JD,QD,KD,AD] # Diamonds.

Рейтинг рук:

1:Royal Flush    (A-K-Q-J-10, all from the same suit).
2:Straight Flush (Sequential cards, all from the same suit).
3:Four-of-a-Kind (Self explanatory).
4:Full House     (3-of-a-kind and a 2-of-a-kind).
5:Flush          (All cards are from the same suit).
6:Straight       (Sequential Cards, any suits).
7:3-of-a-Kind    (Self explanatory).
8:2-Pair         (Double 2-of-a-Kind).
9:Pair           (2-of-a-Kind).
10:High Card     (You have absolutely nothing except a single card).

Давайте візьмемо приклад-два та пройдись по них:

Простий приклад:

[AS, AC],[AH,AD,9S,9C,9H]-> 3(Чотири-від-роду), 3(Чотири-з-роду)

Найкраща рука, яку ви матимете в цьому налаштуванні, - це четверо з добрих рук. Найкраща можлива рука ваших супротивників - це також 4-х-на-виду, так як ви не можете мати KQJ10 у своїх руках з двома картками.


[5C,2C],[6C,4C,JH,JD]-> 2(Прямий флеш), 3(4-х від виду)

Ви ризикуєте отримати прямий флеш, але оскільки у вас 2 / 5C в руці, ніхто більше не зважає на те, що ви тримаєте обидві середні карти. Найкраще, на що вони можуть сподіватися, - це 2 кишенькові джекси та отримання Джека на флопі.


[JS,JC],[]-> 1(Royal Flush), 1(Royal Flush)

Ніякої інформації, яку ви можете використовувати проти них, не було надано, все, що ви можете сказати на даний момент, - це те, що вони можуть мати тільки королівський флеш в діамантах / сердечках, але так само можливо, що ви отримаєте королівський флеш, як і вони. Насправді, на всі входи, де флоп ще не відбувся, слід отримати відповідь 1-1.


[2C,4S],[3C,7S,9D,AH,JD]-> 10(Висока карта), 7(3-х вид)

Це приклад того, коли ви абсолютно закручені, і немає можливості повороту чи рум'яну з-за річки. Означення найкращої руки тут - кишенькові тузи, що призводять до 3-х видів.


Вимоги вводу / виводу

  • Вхід повинен бути розділений між тим, що є у вас в руці, і тим, що є суспільними знаннями; це, швидше за все, буде простіше, незалежно від реалізації.
    • Картки можуть бути кортежами або рядками.
    • Рука та ігрове поле можуть бути масивами або обмеженими рядками.
  • Вихідні дані повинні бути двома індексами зі списку поданих мною рук (EG [2,1]).
    • Він може бути повернутий як частину функції, надрукований на консоль або вихід відповідним чином.
    • Повинно бути два чітких значення, одне для вашої найкращої руки, інше для найкращого.
  • 10 може бути представлено як Tабо як 10, що б для вас не було сенсу.
  • Стандартні лазівки заборонені.

Критерії виграшу

  • Це , найнижчий обсяг байтів з вимикачем дати публікації.

2
Чи не повинен бути тільки один з Aі 1в можливих дозволених картах? Крім того, я не думаю, що існує справді вагома причина вимагати абревіатур обличчя над числовими значеннями 11.
FryAmTheEggman


9
Я ніколи не бачив колоду з a Aі a 1. Все інше виглядає добре.
isaacg

1
Для нас, хто не є гравцями в Покер, будь ласка, поясніть у запитанні, що друга група карт поділяється між вами та вашим опонентом, тоді як у них є дві власні карти, які ви не можете бачити. Швидкий словник, що визначає терміни кишеньковий , флоп та рівер , буде корисним.
DLosc

1
Також корисно: пояснення всієї послідовності раунду. (Кожен гравець починає з двох відомих лише їм карт. Потім три карти роздаються обличчям вгору, потім четвертою, потім п'ятою, і в цей момент кожен гравець формує "руку" з будь-яких п'яти карт із семи видимих ​​їм сімей .) Хтось може не зрозуміти, чому є сім карток, але рука складається з п'яти.
DLosc

Відповіді:


3

Haskell , 433 430 425 байт

-5 байт завдяки @Laikoni

import Data.List
q="23456789TJQKA"
e=elem
l=length
b=map
r p|z,elem 'A'u,elem 'K'u=1|z=2|e 4t=3|v<3=4|w=5|y=6|e 3t=7|v<4=8|v<5=9|1>0=10where u=[n!!0|n<-p];v=l$nub u;t=b(\n->l[x |x<-u,x==n])q;w=all(==(last$p!!0))[last s|s<-p];y=elem""[u\\s|s<-b(take 5.flip drop('A':q))[0..10]];z=y&&w
0%_=[[]]
n%(x:y)=b(x:)((n-1)%y)++n%y
_%_=[]
h#t|let p=h++t;c i=minimum$b r$concat$b(5%)$b(++i)((7-l i)%([n:[s]|n<-q,s<-"SCHD"]\\p))=(c p,c t)

Спробуйте в Інтернеті!

Безлічі (та сама ідея, трохи інша структура):

import Data.List -- for (\\)
numbers = "23456789TJQKA"

e=elem

rank_hand hand
    |royal_flush=1
    |straight_flush=2
    |four_of_a_kind=3
    |full_house=4
    |flush=5
    |straight=6
    |three_kind=7
    |two_pair=8
    |pair=9
    |1>0=10
    where nums = [head n | n<-hand]
          unique = length $ nub nums
          counts = map (\n->length [x | x<-nums, x==n]) numbers
          pair = unique < 5
          two_pair = unique < 4 -- could also be 3 of a kind, but that's ok
          three_kind = e 3 counts
          flush = all (==(last$hand!!0)) [last s|s<-hand]
          straight = elem "" [nums\\s | s <- map (take 5.flip drop ('A':numbers))[0..10]]
          full_house = unique < 3
          four_of_a_kind = e 4 counts
          straight_flush = straight && flush
          royal_flush = straight_flush && elem 'A' nums && elem 'K' nums

-- taken from /codegolf//a/34496/66460
-- k%l finds combinations of size k from a list l
0%_=[[]]
n%(x:y)=map(x:)((n-1)%y)++n%y
_%_=[]

-- find every combination available to each player, and rank each one. 
-- could be golfed a lot more.
h#t=let p=h++t
        a=[n:[s]|n<-numbers,s<-"SCHD"]\\p
        c i=minimum $ map rank_hand $ concat $ map (5%) $ map (++i) ((7-length i)%a)
    in(c p,c t)

Дуже повільно, оскільки взагалі немає спеціального корпусу (наприклад, якщо картки не показані, завжди можливий королівський флеш.) Більшість моїх зусиль з гольфу йшла на rank_handроботу; #можна набагато більше гольфу, комбінуючи карти та інше.

hand#tableрозраховує оптимальні бали для вас та вашого опонента. Не перевіряє помилок.


Я думаю, ви забули s/elem/e/gпісля визначення e=elem, так що це повинно заощадити 9ish байтів. Я думаю, ви також можете видалити пробіли, особливо там, де ідентифікатори безпосередньо слідують за номерами
Julian Wolf

@JulianWolf Я все ще новачок у Haskell, але чомусь це виглядає як e=elemвисновок типу Int-> Bool, тому він не компілювався, коли я використовував e для не цілих викликів елем. Я намагаюся з'ясувати, чому це було. Дякую за пораду про місця!
vroomfondel

Ах, ти маєш рацію. У Haskell іноді виникають проблеми з підрахунком поліморфних типів - не впевнений, чи є легкий виправлення, крім додавання прапора гнучких типів
Julian Wolf

1
h#t=let[...]in[...]можна скоротити до h#t|let[...]=[...]. Також head nє n!!0. У охороні &&може бути просто ,.
Лайконі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.