Hold'em czy Fold'em?

17

Twój przyjaciel zaprosił Cię w ostatniej chwili na pokera o wysokie stawki, a jako informatyk postanowiłeś wykorzystać swoje umiejętności, aby uzyskać przewagę nad grą. Twoim zadaniem będzie, biorąc pod uwagę 2 cards(twoją rękę) i 0, 3, 4 or 5 cards(rozdane karty), musisz zdecydować, jaka będzie najlepsza możliwa ręka. Jeśli wszystkie 7 kart podano jako argumenty, odpowiedź jest dość jasna. Jeśli podano mniej, problem staje się bardziej złożony. Jednak to nie wystarczy, aby dać przewagę, której szukasz, musisz również obliczyć najlepszą możliwą rękę z pozostałych kart, aby zrozumieć, co mogą mieć twoi przeciwnicy.


Hold'em Odświeżacz

Jeśli nie wiesz o Hold'em, każdy gracz w grze zaczyna od 2 kart jako „ręki”. W trakcie 3 „tur” ujawnia się, że dodatkowe karty są dzielone między wszystkich graczy. W pierwszej turze zostają ujawnione 3 karty. Druga, jeszcze jedna i po raz trzeci ujawniona jest ostatnia karta. Dwie podane karty jako pierwsze reprezentują twoją rękę, podczas gdy ta druga reprezentuje 0, 3, 4 lub 5 kart podanych w kolejnych turach.


Możliwe liczby:

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

Możliwe kolory:

[S,C,H,D]

Pełna talia:

[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.

Rankingi rąk:

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).

Weźmy przykład lub dwa i przejrzyjmy je:

Prosty przykład:

[AS, AC],[AH,AD,9S,9C,9H]-> 3(Four-of-a-Kind), 3(Four-of-a-Kind)

Najlepszym możliwym układem, jaki będziesz mieć w tym układzie, jest układ czterech kart. Najlepszą możliwą ręką, jaką mogą mieć przeciwnicy, jest również 4-of-a-kind, ponieważ nie możesz mieć KQJ10 w rękach 2 kart.


[5C,2C],[6C,4C,JH,JD]-> 2(Straight Flush), 3(4-of-a-a-kind)

Grozi Ci strit, ale ponieważ masz 2 / 5C na ręce, nikt inny nie jest odpowiedzialny za posiadanie obu środkowych kart. Najlepsze, na co mogą liczyć, to mieć 2 kieszonkowe walety i zdobyć waleta na flopie.


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

Nie podano żadnych informacji, których możesz użyć przeciwko nim, jedyne, co możesz teraz powiedzieć, to to, że mogą mieć tylko królewski kolor w diamentach / sercach, ale możliwe jest, że dostaniesz królewski kolor. W rzeczywistości wszystkie dane wejściowe, na których flop jeszcze się nie wydarzył, powinny dać odpowiedź 1-1.


[2C,4S],[3C,7S,9D,AH,JD]-> 10(High Card), 7(3-of-a-Kind)

Jest to przykład tego, gdzie jesteś absolutnie spieprzony i nie ma możliwości strita lub koloru, biorąc pod uwagę rzekę. Oznacza to, że najlepszą ręką są asy, które dają 3-of-a-kind.


Wymagania we / wy

  • Należy rozdzielić wkład między to, co masz w ręce, a to, co jest wiedzą publiczną; w ten sposób będzie prawdopodobnie łatwiejsze bez względu na implementację.
    • Karty mogą być krotkami lub ciągami, zależnie od Ciebie.
    • Ręka i pole gry mogą być tablicami lub ograniczonymi łańcuchami.
  • Dane wyjściowe muszą być dwoma indeksami z listy rąk, które podałem (EG [2,1]).
    • Może zostać zwrócony jako część funkcji, wydrukowany na konsoli lub wydrukowany w odpowiedni sposób.
    • Muszą być dwie różne wartości, jedna dla najlepszego układu, druga dla najlepszego możliwego układu.
  • 10 może być reprezentowane jako Tlub jako 10, w zależności od tego, co ma dla ciebie sens.
  • Standardowe luki są niedozwolone.

Zwycięskie kryteria

  • To jest , najniższa liczba bajtów z rozstrzygającym terminem posta.
Urna Magicznej Ośmiornicy
źródło
2
Nie powinno tam być tylko jeden Ai 1na możliwych dozwolonych kart? Nie sądzę też, aby istniał naprawdę ważny powód, aby wymagać skrótów twarzy od wartości liczbowych, takich jak 11.
FryAmTheEggman
9
Nigdy nie widziałem talii z Ai 1. Wszystko inne wygląda dobrze.
isaacg
1
Dla nas, którzy nie grają w pokera, wyjaśnij w pytaniu, że druga grupa kart jest dzielona między tobą a twoim przeciwnikiem, podczas gdy mają one własne dwie karty, których nie widać. Pomocny byłby szybki słownik terminów pocket , flop i river .
DLosc
1
Pomocne również: wyjaśnienie całej sekwencji rundy. (Każdy gracz zaczyna od dwóch znanych tylko sobie kart, następnie rozdaje się trzy odkryte karty, następnie czwartą, potem piątą, w którym to momencie każdy gracz tworzy „rękę” z dowolnych pięciu z siedmiu widocznych dla nich kart .) Może nie być dla kogoś jasne, dlaczego jest siedem kart, ale ręka składa się z pięciu.
DLosc

Odpowiedzi:

3

Haskell , 433 430 425 bajtów

-5 bajtów dzięki @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)

Wypróbuj online!

Niegolfowany (ten sam pomysł, nieco inna struktura):

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)

Bardzo wolno, ponieważ w ogóle nie ma żadnej specjalnej obudowy (np. Jeśli nie pokazano żadnych kart, zawsze możliwe jest pokera królewskiego.) Większość mojego wysiłku w golfa poszła w tę rank_handfunkcję; #można grać w golfa o wiele więcej, łącząc mapy i tym podobne.

hand#tableoblicza optymalne wyniki dla ciebie i twojego przeciwnika. Nie sprawdza błędów.

vroomfondel
źródło
Myślę, że zapomniałeś s/elem/e/gpo zdefiniowaniu e=elem, aby zaoszczędzić 9 bajtów. Myślę, że możesz także usunąć niektóre spacje, szczególnie tam, gdzie identyfikatory następują bezpośrednio po liczbach
Julian Wolf,
@JulianWolf Wciąż jestem nowy w Haskell, ale z jakiegoś powodu wygląda to jak e=elemwywnioskowany typ Int-> Bool, więc nie kompilował się, kiedy użyłem e do wywołań elem niecałkowitych. Próbuję dowiedzieć się, dlaczego tak było. Dzięki za wskazówkę dotyczącą spacji!
vroomfondel
Ach, masz rację. Haskell czasami ma problem z wnioskiem o typach polimorficznych - nie jestem pewien, czy istnieje łatwa poprawka, poza dodaniem flagi typów elastycznych
Julian Wolf
1
h#t=let[...]in[...]można skrócić do h#t|let[...]=[...]. Też head njest n!!0. W straży &&może być po prostu ,.
Laikoni