¿Hold'em o Fold'em?

17

Tu amigo te invitó a un juego de póker de alto riesgo en el último minuto y, como científico de la computación, decidiste usar tus habilidades para obtener una ventaja en el juego. Su tarea será, dada 2 cards(su mano) y 0, 3, 4 or 5 cards(las cartas repartidas), debe decidir cuál será la mejor mano posible. Si las 7 cartas se dan como argumentos, la respuesta es bastante clara. Si se le da menos, el problema se vuelve más complejo. Sin embargo, esto no es suficiente para darte la ventaja que estás buscando, también debes calcular la mejor mano posible de las cartas restantes para comprender lo que tus oponentes podrían tener también.


Hold'em Refresher

Si no sabe acerca de hold'em, cada jugador en el juego comienza con 2 cartas como su "mano". En el transcurso de 3 'turnos', se revela que se comparten cartas adicionales entre todos los jugadores. El primer turno, se revelan 3 cartas. La segunda, 1 más, y la tercera vez que se revela una carta final. Las dos cartas dadas primero representan tu mano, mientras que la última representa 0, 3, 4 o 5 cartas dadas por los turnos sucesivos.


Números Posibles:

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

Trajes posibles:

[S,C,H,D]

Cubierta completa:

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

Clasificación de manos:

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

Tomemos un ejemplo o dos y analicemos:

El ejemplo simple:

[AS, AC],[AH,AD,9S,9C,9H]-> 3(Cuatro de una especie), 3(Cuatro de una especie)

La mejor mano posible que tendrás en esta configuración es la mano cuatro de un tipo. La mejor mano posible que podrían tener tus oponentes es también un 4-of-a-Kind, ya que no puedes tener un KQJ10 en sus manos de 2 cartas.


[5C,2C],[6C,4C,JH,JD]-> 2(Escalera de color), 3(4 de una especie)

Corre el riesgo de una escalera de color, pero debido a que tiene el 2 / 5C en su mano, nadie más se debe a que tenga ambas cartas intermedias. Lo mejor que pueden esperar es tener 2 Jacks de bolsillo y obtener un Jack en el flop.


[JS,JC],[]-> 1(Escalera Real), 1(Escalera Real)

No se ha proporcionado información que pueda usar contra ellos, todo lo que puede decir en este momento es que solo pueden tener una escalera real en diamantes / corazones, pero es tan posible que obtenga la escalera real como lo hacen. De hecho, todas las entradas en las que el flop aún no ha sucedido deberían dar como resultado una respuesta 1-1.


[2C,4S],[3C,7S,9D,AH,JD]-> 10(Carta alta), 7(3-de-una-clase)

Este es un ejemplo de dónde estás absolutamente jodido, y no hay posibilidad de una escalera o un color dado el río. Lo que significa que la mejor mano aquí son los ases de bolsillo que dan como resultado un 3 de una especie.


Requisitos de E / S

  • La entrada debe estar separada entre lo que está en su mano y lo que es de conocimiento público; probablemente sea más fácil de esta manera, independientemente de la implementación.
    • Las tarjetas pueden ser tuplas o cadenas, depende de usted.
    • La mano y el campo de juego pueden ser matrices o cadenas delimitadas.
  • La salida debe ser dos índices de la lista de manos que he proporcionado (EG [2,1]).
    • Puede devolverse como parte de una función, imprimirse en la consola o imprimirse de manera adecuada.
    • Debe haber dos valores distintos, uno para su mejor mano, otro para la mejor posible.
  • 10 puede representarse como a To como 10, lo que tenga sentido para usted.
  • Las lagunas estándar no están permitidas.

Criterios ganadores

  • Este es el , el conteo de bytes más bajo con un desempate de la fecha de publicación.
Urna de pulpo mágico
fuente
2
¿No debería haber solamente uno de Ay 1en las posibles tarjetas permitidos? Además, no creo que haya una razón convincente para exigir las abreviaturas de la cara sobre valores numéricos como 11.
FryAmTheEggman 01 de
9
Nunca he visto una baraja con una Ay una 1. Todo lo demás se ve bien.
isaacg 01 de
1
Para nosotros, que no somos jugadores de póker, explique en la pregunta que el segundo grupo de cartas se comparte entre usted y su oponente, mientras que tienen sus propias dos cartas que no puede ver. Sería útil un glosario rápido que defina los términos bolsillo , flop y river .
DLosc
1
También es útil: explicar la secuencia completa de una ronda. (Cada jugador comienza con dos cartas conocidas solo por ellos, luego se reparten tres cartas boca arriba, luego una cuarta, luego una quinta, en cuyo punto cada jugador forma una "mano" de cinco cartas de las siete visibles para ellos .) Puede que no esté claro para alguien por qué hay siete cartas, pero una mano consta de cinco.
DLosc 01 de

Respuestas:

3

Haskell , 433430425 bytes

-5 bytes gracias a @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)

Pruébalo en línea!

Sin golf (misma idea, estructura ligeramente diferente):

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)

Muy lento, ya que no hay una carcasa especial en absoluto (por ejemplo, si no se han mostrado cartas, siempre es posible un color real). La mayor parte de mi esfuerzo de golf fue para la rank_handfunción; #se puede jugar mucho más al golf combinando mapas y demás.

hand#tablecalcula los puntajes óptimos para usted y su oponente. No hay comprobación de errores.

vroomfondel
fuente
Creo que se olvidó s/elem/e/gdespués de definir e=elem, por lo que debería ahorrarle 9ish bytes. Creo que también puedes eliminar algunos espacios, particularmente donde los identificadores siguen a los números directamente
Julian Wolf
@JulianWolf Todavía soy nuevo en Haskell, pero por alguna razón parece un tipo e=eleminferido Int-> Bool, por lo que no se estaba compilando cuando usaba e para llamadas de elementos no enteros. Estoy tratando de entender por qué. Gracias por el consejo en los espacios!
vroomfondel
Ah, tienes razon. Haskell tiene problemas para inferir tipos polimórficos a veces, no estoy seguro de si hay una solución fácil, más allá de agregar la bandera de tipos flexibles
Julian Wolf
1
h#t=let[...]in[...]se puede acortar a h#t|let[...]=[...]. También head nes n!!0. En una guardia &&puede ser simplemente ,.
Laikoni