Pergunta

Para uma lição de casa foi-me dada uma classe cartão que enumerou tipos para o valor e naipe. Eu sou obrigado a comparar duas mãos de poker (cada mão é uma ArrayList de 5 cartas) e decidir o vencedor.

A função isStraight() realmente está me incomodando, porque eu tenho que começar de novo a contagem após o Ace. Por exemplo,

rainha, rei, ACE, dois, três

ainda é considerada uma reta. Qual é a melhor maneira de código essa funcionalidade?

Aqui está o terno enumerado / código de tipo Rank, se isso ajuda.

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;
}
Foi útil?

Solução

Você percebe que pelas regras de qualquer jogo de poker que já jogou ou ouviu falar de uma reta não pode envolver certo? Ás pode ser baixo [A, 2,3,4,5] ou alta [10, J, Q, K, A], mas ele não pode quebrar. De acordo com essas regras (não seu) Eu tenho implementado algo semelhante antes. Basicamente você classificar a matriz e caminhar-lo, certificando-se o cartão atual é maior do que o anterior. Na primeira iteração, se for um ás, então você verificar explicitamente para [A, 2,3,4,5]. Se é você retornar verdadeiro e se não é você continuar com a lógica reta normal. Isto deve ajustá-lo na direção certa.

Outras dicas

Uma boa abordagem para a resolução de mãos de poker em geral é a de atribuir cada cartão um valor bit com o bit ((rank-2) * 2) conjunto de bits, bem como bit (terno + 28) set, (assim 2 = 1, 3 = 4, 4 = 16, etc, até a a = 0x1000000). Em seguida, adicione juntos todos os cartões (chamada que resultado 'Sum'. Compute V1 = (Soma & 0x2AAAAAA) >> 1, V0 = (soma & 0x1555555), e V2 = V1 e V0., Também ou em conjunto os valores para as cinco cartas e computação V3 = OrValue & 0xF0000000;

  1. Para um par, V1 terá um conjunto único bit, V0 terá vários bits definidos, e V2 será zero.
  2. Para dois pares, V1 terá dois bits definir e V2 será igual a zero.
  3. Para um três-of-a-kind, V1 terá um conjunto único bit, e V2 será igual a V1.
  4. Para uma reta, V0 será ou 0x1000055 ou então um múltiplo potência de dois dos 0x155.
  5. Para um flush, V2 terá precisamente um conjunto de bits.
  6. Para uma casa cheia, V1 terá dois bits definido, e V2 será diferente de zero.
  7. Para quatro-de-um-tipo, V1 será v0 duas vezes, com ambos tendo um conjunto de bits, ou V0 terá precisamente dois bits definir e V1 será zero.
  8. Para um straight flush, serão atendidas as condições para straight flush e.

A testes exigidos para esta abordagem deve ser exequível rapidamente com uma quantidade mínima de ramificação.

Você poderia escrever um algoritmo de fantasia para retornar verdadeiro apesar do número de cartas possíveis, mas se você perceber que há apenas 10 combinações válidas em uma mão ordenada, você pode simplesmente olhar para estes:

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

Uma vez que há apenas 5 cartões em você lista, você pode classificá-lo e determinar a diferença entre 2 cartas consecutivas. Se ele contém um ás, você precisa considerá-lo como um cartão de baixo também. se todas as diferenças são 1 (ou -1, dependendo da ordem de classificação), você tem seu direto.

Eu diria que, dado que a definição de RANK, que rectas só pode começar com um máximo de ACE.points () -. 4

Então, se você classificar sua mão e o menor RANK é> ACE.points () - 4 então você não pode ter uma reta, caso contrário, você apenas iterar sobre a mão para ver que cada cartão é RANK anterior + 1.

Se ACE pode ser alto ou baixo, em seguida, ir com o que SHS respondeu.

Com um loop interno é bastante trivial, o desafio seria fazê-lo sem um loop interno ...

Além disso, ele depende se você entendeu o seu professor ou sua incompreendido professor (ou deturpado) as regras do jogo.

Eu acho que eu estaria tentado a criar um array [2..14] e colocar as cartas na localização que corresponde ao seu posto. Se você acertar um duplicado, não é uma linha reta, e quando você é feito, você deve ter 8 espaços em uma fileira. Se você tiver menos de 8 espaços em uma linha, que não é uma linha reta.

Todas as outras soluções que podem chegar a requerer um loop interno -. E laços internos é uma daquelas coisas desleixado programação que você precisa evitar, sempre que possível se você estiver indo para nunca ser um programador respeitável

edit: Além disso, se você entendeu mal o professor ea condição só embrulho é "10, j, q, k, a" (como nas regras de reais), então você precisa de um teste adicional que, se tudo de 2, 13 e 14 estão definidos, é também uma falha (wraparound 2-ak).

(editado novamente para substituir 1 para ace com 14 depois de reler a pergunta)

Eu não uso enum muito, eu prefiro constantes nomeadas, mas eu vou assumir que vai de "ACE" para "14" é trivial

eu sou muito preguiçoso para escrever código java real (ao lado você realmente tem que fazer sua lição de casa ^^)

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

O operador% é chamado módulo de modo (15% 13) 2 == Eu uso este operador sempre que enfrentar o "envoltório over" desafio

Edit: Depois de reler a sua pergunta minha solução pode não funcionar fora da caixa. Você deve reordenar a sua enumeração de modo que dois == 0

Eu recomendo usar um vetor de bits para representar os cartões. Isso evita ter que classificar. Você pode adicionar o ás duas vezes (uma vez como uma das outras vezes como um rei) ou você pode caso especial da situação de partida, verificando se o bit ace é definida antes de verificar se o 2 é definido). Você pode construir um grande olhar para cima da tabela se a velocidade é importante. Essa abordagem também limpeza escalas para encontrar o resto das mãos (rubores, 2 pares, casas completas, viagens, e assim por diante). Também torna mais fácil descobrir se uma determinada linha reta é maior do que o outro. E ele se expande de forma limpa de 7 card avaliador

No código pseudo que é algo como isto para um caso muito geral (você pode ter qualquer número de cartões. Ele retorna a primeira reta)

 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

Adicionar todas as fileiras, a fim de uma lista, duas vezes. Então, para verificar se a mão é uma reta, tipo a mão por posto e, em seguida, verificar se a mão é uma sub-lista da lista.

Você poderia escrever uma classe que converte todos os cartões a um valor determinado cartão

Joker = 11 Rainha = 12 Rei = 13 Ace = 0 ou 14

ele vai fazer a manipulação do cartão muito mais fácil e procura de possíveis mãos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top