Hold'em ou Fold'em?

17

Votre ami vous a invité à un jeu de poker à enjeux élevés à la dernière minute et, en tant qu'informaticien, vous avez décidé d'utiliser vos compétences pour prendre l'avantage sur le jeu. Votre tâche sera, étant donné 2 cards(votre main) et 0, 3, 4 or 5 cards(les cartes distribuées), vous devez décider quelle sera la meilleure main possible. Si les 7 cartes sont fournies comme arguments, la réponse est assez claire. S'il est donné moins, le problème devient plus complexe. Cependant, cela ne suffit pas pour vous donner l'avantage que vous recherchez, vous devez également calculer la meilleure main possible à partir des cartes restantes pour comprendre ce que vos adversaires pourraient également avoir.


Rappel de Hold'em

Si vous ne connaissez pas le Hold'em, chaque joueur du jeu commence avec 2 cartes comme «main». Au cours de 3 «tours», des cartes supplémentaires se révèlent être partagées entre tous les joueurs. Le premier tour, 3 cartes sont révélées. La deuxième, 1 de plus et la troisième fois, une dernière carte est révélée. Les deux cartes données en premier représentent votre main, tandis que celle-ci représente 0, 3, 4 ou 5 cartes données par les tours successifs.


Numéros possibles:

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

Costumes possibles:

[S,C,H,D]

Pont complet:

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

Classements des mains:

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

Prenons un exemple ou deux et parcourons-les:

L'exemple simple:

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

La meilleure main possible que vous aurez dans cette configuration est la main unique. La meilleure main possible que vos adversaires pourraient avoir est également un 4-of-a-Kind, car vous ne pouvez pas avoir un KQJ10 dans leurs mains à 2 cartes.


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

Vous êtes à risque pour une quinte flush, mais parce que vous avez le 2 / 5C en main, personne d'autre ne doit vous tenir les deux cartes du milieu. Le mieux qu'ils puissent espérer est d'avoir 2 Jacks de poche et d'avoir un Jack au flop.


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

Aucune information que vous pouvez utiliser contre eux n'a été donnée, tout ce que vous pouvez dire pour le moment, c'est qu'ils ne peuvent avoir qu'une couleur royale dans les diamants / coeurs, mais il est tout aussi possible que vous obteniez la couleur royale comme eux. En fait, toutes les entrées où le flop n'a pas encore eu lieu devraient entraîner une réponse 1-1.


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

Ceci est un exemple de l'endroit où vous êtes absolument foutu, et il n'y a aucune possibilité d'une ligne droite ou d'une chasse d'eau compte tenu de la rivière. Ce qui signifie que la meilleure main ici est des as de poche, ce qui donne un 3-of-a-Kind.


Exigences d'E / S

  • L'apport doit être séparé entre ce qui est dans votre main et ce qui est du public; ce sera probablement plus facile de cette façon, quelle que soit la mise en œuvre.
    • Les cartes peuvent être des tuples ou des chaînes, selon vous.
    • La main et le terrain de jeu peuvent être des tableaux ou des chaînes délimitées.
  • La sortie doit être deux index de la liste des mains que j'ai fournies (EG [2,1]).
    • Il peut être renvoyé dans le cadre d'une fonction, imprimé sur la console ou sorti d'une manière appropriée.
    • Il doit y avoir deux valeurs distinctes, l'une pour votre meilleure main, l'autre pour la meilleure possible.
  • 10 peut être représenté comme un Tou comme 10, selon ce qui vous convient .
  • Les failles standard ne sont pas autorisées.

Critères gagnants

  • Il s'agit du , le nombre d'octets le plus bas avec un bris d'égalité de la date de publication.
Urne de poulpe magique
la source
2
Ne devrait-il pas y avoir qu'une seule Aet parmi 1les éventuelles cartes autorisées? De plus, je ne pense pas qu'il y ait vraiment une raison impérieuse d'exiger les abréviations de visage sur des valeurs numériques comme 11.
FryAmTheEggman
9
Je n'ai jamais vu de deck avec un Aet un 1. Tout le reste a l'air bien.
isaacg
1
Pour nous non-joueurs de Poker, veuillez expliquer dans la question que le deuxième groupe de cartes est partagé entre vous et votre adversaire, alors qu'ils ont leurs propres deux cartes que vous ne pouvez pas voir. Un glossaire rapide définissant les termes poche , flop et rivière serait utile.
DLosc
1
Également utile: expliquer toute la séquence d'un tour. (Chaque joueur commence avec deux cartes connues seulement d'eux, puis trois cartes sont distribuées face visible, puis une quatrième, puis une cinquième, à ce moment chaque joueur forme une "main" à partir de cinq cartes parmi les sept visibles pour lui. .) Il peut ne pas être clair pour quelqu'un pourquoi il y a sept cartes, mais une main se compose de cinq.
DLosc

Réponses:

3

Haskell , 433 430 425 octets

-5 octets grâce à @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)

Essayez-le en ligne!

Non golfé (même idée, structure légèrement différente):

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)

Très lent, car il n'y a pas de boîtier spécial du tout (par exemple, si aucune carte n'a été montrée, un flush royal est toujours possible.) La plupart de mes efforts de golf sont allés dans la rank_handfonction; #peut être joué beaucoup plus en combinant des cartes et autres.

hand#tablecalcule les scores optimaux pour vous et votre adversaire. Ne vérifie pas les erreurs.

vroomfondel
la source
Je pense que vous avez oublié de le s/elem/e/gdéfinir e=elem, ce qui devrait vous faire économiser 9 octets. Je pense que vous pouvez également supprimer certains espaces, en particulier lorsque les identifiants suivent directement les chiffres
Julian Wolf
@JulianWolf Je suis encore nouveau pour Haskell, mais pour une raison quelconque, il ressemble au type e=eleminféré Int-> Bool, donc il ne se compilait pas lorsque j'utilisais e pour des appels elem non entiers. J'essaie de comprendre pourquoi. Merci pour le conseil sur les espaces!
vroomfondel
Ah, tu as raison. Haskell a parfois du mal à déduire les types polymorphes - je ne sais pas du haut de ma tête s'il existe une solution facile, au-delà de l'ajout du drapeau des types flexibles
Julian Wolf
1
h#t=let[...]in[...]peut être raccourci h#t|let[...]=[...]. Aussi head nest n!!0. Dans une garde &&peut être tout simplement ,.
Laikoni