Pregunta

Para la realización de una tarea que se me había dado una Tarjeta de la clase que ha enumerado los tipos de valor y un Palo.Estoy obligado a comparar dos manos de poker (cada mano es un ArrayList de 5 cartas) y decidir el ganador.

El isStraight() la función que realmente me molesta, porque tengo que empezar de nuevo el conteo después de la Ace.Por ejemplo,

REINA, REY, AS, DOS, TRES

Todavía se considera una recta.¿Cuál es la mejor forma de código de esta funcionalidad?

Aquí es el Rango/Traje de tipo enumerado código, si eso ayuda.

public enum Rank
{
    TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9),
    TEN(10), JACK(11), QUEEN(12), KING(13), ACE(14);

    private final int points;

    private Rank(int points)
    {
        this.points = points;
    }

    public int points()
    {
        return this.points;
    }
}

public enum Suit
{
    DIAMONDS, CLUBS, HEARTS, SPADES;
}
¿Fue útil?

Solución

¿Se da cuenta de que por las reglas de cualquier juego de póquer que he jugado o escuchado de una recta no puede envolver la derecha? As puede ser baja [A, 2,3,4,5] o alta [10, J, Q, K, A] pero no puede envolver. De acuerdo con esas reglas (no el suyo) He implementado algo similar antes. Básicamente se ordena la matriz y camina ella, asegurándose de que la tarjeta actual es uno más alto que el anterior. En la primera iteración, si es un as, entonces se comprueba de manera explícita [A, 2,3,4,5]. Si es cierto que regrese y si no es de continuar con la lógica recta normal. Esto se debe configurar en la dirección correcta.

Otros consejos

Un acercamiento agradable para la resolución de las manos de póquer en general es asignar a cada tarjeta de un valor de bit con el bit ((* 2 rango-2)) (+ 28 traje) Juego de conjunto de bits, así como poco, (SO2 = 1, 3 = 4, 4 = 16, etc. hasta a = 0x1000000). A continuación, añadir todas las tarjetas (llaman a ese resultado 'suma'. Calcular V1 = (Suma y 0x2AAAAAA) >> 1, V0 = (Suma y 0x1555555), y V2 = V1 y V0. También O juntos los valores para las cinco cartas y calcular V3 = OrValue y 0xF0000000;

  1. Para un par, V1 tendrá un único conjunto de bits, V0 tendrá establecen múltiples bits, y V2 será cero.
  2. Para-dos pares, V1 se han fijado dos bits y V2 será igual a cero.
  3. Para un niño de tres de su tipo, V1 tendrá un único conjunto de bits, y V2 será igual a V1.
  4. Para una recta, V0 o bien será 0x1000055 o bien un múltiplo de potencias de dos de 0x155.
  5. Para un color, V2 tendrá exactamente un conjunto de bits.
  6. En una casa completa, V1 se han fijado dos bits, y V2 será distinto de cero.
  7. Para cuatro de-a-tipo, ya sea V1 serán dos veces v0, con tanto que tiene un conjunto de bits, o V0 tendrán fijado de manera precisa y dos bits y V1 serán cero.
  8. Para una escalera de color, se cumplen las condiciones de escalera y color.

Esta pruebas requeridas para este enfoque debe ser implementable rápidamente con una cantidad mínima de ramificación.

Se puede escribir un algoritmo de fantasía para volver así a pesar de que el número de posibles tarjetas, pero si se da cuenta que sólo hay 10 combinaciones válidas en una mano ordenada, sólo podría buscar los siguientes:

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

Dado que sólo hay 5 cartas en que la lista, que podría solucionar el problema y determinar la diferencia entre 2 cartas consecutivas. Si contiene un as, es necesario considerarlo como una carta baja también. si todas las diferencias son 1 (o -1, dependiendo del orden de clasificación), que tiene su recta.

Yo diría que, dado que la definición de RANK, que rectas sólo pueden comenzar con un máximo de ACE.points () -. 4

Así que si ordena la mano y el rango más bajo es> ACE.points (4) - entonces usted no puede tener una recta, de lo contrario simplemente iterar sobre la mano para ver que cada tarjeta es RANK anterior + 1.

Si la ECA puede ser alto o bajo, entonces ir con lo que respondió SHS.

Con un bucle interno es bastante trivial, el reto sería hacerlo sin un bucle interno ...

Además, depende de si usted entiende a su maestro o su mal entendido profesor (o mal representado) las reglas del juego.

Creo que estaría tentado a crear un array [2..14] y colocar las tarjetas en el lugar que corresponde a su rango. Si llega a un duplicado, no es una recta, y cuando haya terminado, usted debe tener 8 espacios en una fila. Si tiene menos de 8 espacios en una fila, no es una recta.

Todas las otras soluciones que se me ocurre con requieren un bucle interno - y bucles internos son una de esas cosas de programación descuidados que debe evitar siempre que pueda, si usted va a ser cada vez un programador respetable

Edit: Además, si usted entendió mal el maestro y la única condición envoltura es "10, J, Q, K, A" (como en las reglas reales), entonces usted necesita una prueba adicional de que si todos los 2, 13 y 14 están situados, es también un fracaso (envolvente 2-ak).

(Editado nuevo para reemplazar 1 para as con 14 después de volver a leer la pregunta)

Yo no uso mucho más constantes de enumeración, prefiero nombra pero voy a suponer que va de "ACE" a "14" es trivial

Soy demasiado vago para escribir código Java real (al lado que realmente tiene que hacer su tarea ^^)

check if the list has 5 cards
convert card names to a card number list named array
sort the list array
for i=1 to 4
if not (array[i] + 1) % 13 == (array[i+1]) % 13
then it is not a straight

El operador% se llama módulo de modo (15% 13) == 2 Yo uso este operador cada vez que se enfrentan al reto "wrap sobre"

Editar: Después de volver a leer su pregunta mi solución no puede funcionar fuera de la caja. Usted debe cambiar el orden de su enumeración de modo que dos == 0

Recomiendo el uso de un vector de bits para representar a las cartas.Esto evita tener que ordenar.Usted puede agregar el ace dos veces (una vez como 1 de las otras veces como un rey), o el caso especial de la situación de partida mediante la comprobación de si el ace poco se establece antes de comprobar si los 2 se establece).Usted puede construir un gran look up table si la velocidad de la materia.Este enfoque también la limpieza de las escalas para encontrar el resto de las manos (color, 2 pares, lleno de casas, viajes, etc).También hace que sea fácil de averiguar si una recta es mayor que la otra.Y se expande de manera limpia 7 card evaluador

En pseudo-código, se ve algo como esto para un caso general (que puede tener cualquier número de cartas.Devuelve la primera recta)

 long cardBitMask
 for each card in hand
   setBit in cardBitMask

 hearts = mask(cardBitMask)
 diamonds = mask(cardBitMask)
 clubs = mask(cardBitMask)
 spades = mask(cardBitMask)

 // find straight
 uniqueCards = hearts|diamonds|clubs|spades
 int cardsInaRow = 0
 if uniqueCards&AceCardMask:
    cardsInaRow = 1
 for card = 2...King
   if uniqueCards&(1<<card)
      cardsInARow++
   else 
      if cardsInARow == 5
         break
      cardsInARow = 0
 if cardsInARow==5:
     return true
 return false

Añadir todas las filas con el fin de una lista, dos veces. A continuación, para comprobar si una mano es una recta, ordenar la mano por la fila y luego comprobar si la mano es una lista secundaria de esa lista.

podría escribir una clase que convierte cada tarjeta a un determinado valor de la tarjeta

Joker = 11 La reina = 12 El rey = 13 As = 0 o 14

esto hará mucho más fácil la tarjeta de manejo y buscando posibles manos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top