Eu tenho feito um jogo de Texas Hold'Em como parte de uma avaliação e tenho pensado em como examinar as 7 cartas disponíveis e determinar se existem mãos.
O único método possível em que consigo pensar é classificar as cartas numericamente, depois examinar cada grupo possível de 5 cartas e verificar se elas correspondem a uma lista de todas as mãos possíveis. Isso levaria muito tempo e só seria possível para determinar pares, pois o processo é irrelevante.
As cartas são cada sequência, composta de um número / a / j / q / k e um naipe (char)3
(que faz um pequeno símbolo de espadas).
Alguém tem alguma sugestão, fórmula ou link que eu possa usar para ajudar a criar um sistema de análise manual?
Não se preocupe em posicionar as mãos uma contra a outra ainda, isso é uma chaleira diferente de peixe.
Respostas:
Eu acho que você pode encontrar a maioria das mãos de poker simplesmente fazendo algumas mesas com quantas cartas na mão há de cada nível e naipe.
Em outras palavras, crie um ranking de cartas de mapeamento de matriz (números e A / J / Q / K) para a contagem de cartas dessa classificação na sua mão. Se o jogador tiver um par ou três do mesmo tipo, haverá um elemento nesse array igual a 2 ou 3, etc. Eles terão um full house se houver um elemento que é 2 e outro que é 3, e um straight se houver cinco elementos consecutivos iguais a 1 nessa matriz.
Da mesma forma, você pode fazer uma matriz semelhante da contagem de cartas de cada naipe e usá-la para detectar descargas.
Depois de detectar a presença de uma mão específica, é muito fácil voltar e encontrar os cartões específicos na mão, destacando-os na interface do usuário ou o que você precisar fazer.
No pseudocódigo:
fonte
É um pouco complicado, porque há muitas combinações. Felizmente, você tem um processador que pode verificar um grande número de combinações em um tempo muito curto.
Você precisará de algumas estratégias diferentes para detectar diferentes tipos de mãos. Felizmente, alguns dos diferentes tipos podem se sobrepor a estratégias. Eu procuraria, por ordem de posição da mão.
2
,3
,6
,7
,8
São todos contagem simples. Usando uma lista de cartas Ás a Rei, basta colocar o número de cada valor na lista, aumentando para cada carta adicional encontrada. Em seguida, verifique a lista em busca de 4s, se não houver 4s, você não possui um 4 do tipo. Verifique se há 3s, se não houver 3s, você não possui um 3 do mesmo tipo. Se você tem um 3, verifique um 2 (indicando casa cheia). E assim por diante...Para
1
,5
você pode usar a mesma lista e procurar seqüências em que todos os cartões tenham uma ou mais entradas na lista para uma sequência de 5 cartões. Se eles também têm o mesmo naipe, é um straight flush.4
pode ter a mesma configuração de lista, mas desta vez você está contando o processo. Procure números de 5 ou mais.Finalmente,
9
você tem a carta mais alta, o que deve ser uma simples questão de olhar para o último valor mais alto de uma de suas listas acima.Você pode sair assim que encontrar uma correspondência, se pesquisar em ordem. Embora seja trivial continuar a pesquisa e encontrar todas as correspondências, se você deseja fornecer todas essas informações ao usuário.
Essencialmente, você está enchendo baldes. Em seguida, verifique se há combinações nos baldes. Ilustrar:
Começando com uma matriz, com um balde para cada cartão, percorra os cartões e conte a instância de cada cartão. Em seguida, você pode facilmente iterar a matriz e verificar determinadas combinações. Neste exemplo, é claro que existe um tipo 4, porque um dos baldes possui 4 itens.
fonte
Eu me deparei com esse algoritmo uma vez. Multiplica números primos para determinar as mãos e é uma leitura muito interessante. Avaliador de mãos de pôquer de Cactus Kev
fonte
Para complementar as excelentes respostas que essa pergunta já obteve, pensei que seria útil oferecer uma das maneiras mais diretas de comparar mãos uma vez que a técnica básica de classificação foi implementada. Antes de tudo, convém marcar as mãos com a classe , como sugeriram várias respostas - a maioria de suas comparações de 'mão X é melhor que mão Y?' Isso pode ser feito apenas comparando as classes das duas mãos e vendo qual classe é melhor. Quanto ao resto, você realmente precisará comparar cartão por cartão, e acontece que um pouco mais de trabalho na classificação tornará isso mais fácil.
Como o caso de linha de base, considere a situação em que ambas as mãos são 'high card'; nesse caso, você compararia primeiro as duas cartas mais altas e depois (se corresponderem) as próximas duas cartas, etc. esta:
Agora, a boa notícia: acontece que essa ordem lexicográfica , adequadamente ajustada, funciona para comparar duas mãos em qualquerdas classes, desde que a classe seja a mesma. Por exemplo, como a maneira de comparar pares é comparar os pares primeiro, depois as outras três cartas, você pode classificar sua mão para colocar o par primeiro (ou mesmo uma carta do par primeiro!) E executar essa mesma comparação. (Por exemplo, uma mão como A9772 seria armazenada como 77A92 ou, melhor ainda, 7A927; a mão A9972 seria armazenada como 9A729 e, comparando com o código acima, você começaria colocando 7 contra 9 e descobrisse que A9972 ganhou). Uma mão de dois pares seria armazenada com o mais alto dos dois pares primeiro, depois o mais baixo e depois o 'kicker' (assim, por exemplo, A9977 seria armazenado como 97A97); três desse tipo seriam armazenados com uma carta das três primeiro, depois os kickers e depois as outras cartas (por exemplo, A7772 seria 7A277); uma casa cheia seria armazenada com um de seus três e, em seguida, um de seus dois (por exemplo, 99777 seria armazenado como 79779); e straights e flushes podem ser armazenados na ordem 'lexicográfica direta', pois são comparados da mesma forma que as mãos com cartas altas. Isso leva a uma função comparadora externa direta que funciona para todas as classes de mãos com a função já fornecida:
Espero que isso ajude!
fonte
Existem algumas paralelizações possíveis usando representações de cartão adequadas e ajustes de bits. Por exemplo, este código Java avalia hards de 7 cartas retornando um número inteiro que pode ser usado para comparar duas mãos. Pode ser adaptado para relatar o tipo de mão de uma maneira mais amigável. As idéias centrais vêm da página de Cactus Kev mencionada em uma resposta anterior.
Se você está interessado apenas em possíveis implementações para nomear a mão em vários idiomas, em vez de eficiência e clareza de código, você também pode olhar para o desafio Nome da mão de pôquer no codegolf.SE.
fonte
Primeiro, você precisa conhecer o ranking e o naipe de todas as cartas; trivial, mas necessário.
Em seguida, gire essas 7 cartas e crie dois histogramas; um por classificação (usando uma matriz com 13 índices, todos inicializados em zero e incrementado em 1 se e quando uma carta na mão com essa classificação for encontrada) e uma por naipe (usando uma matriz de quatro elementos construídos de maneira semelhante à classificação) . Essas são operações lineares e você pode realizar as duas operações para cada cartão para apenas um conjunto de travessias.
Você pode determinar se alguma das seguintes mãos existe simplesmente examinando cada histograma em busca de intervalos correspondentes aos critérios e / ou um simples teste de acompanhamento:
Naturalmente, você pode combinar várias dessas verificações:
Basicamente, se as respostas a essas perguntas renderem alguma mão, defina o valor resultante da "força da mão" com a força da mão encontrada, se o valor ainda não estiver maior. Por exemplo, se você tem uma casa cheia, a força 7 de 9, também possui uma trinca, força 4, e um par, força 2.
Existem alguns atalhos e saídas rápidas, mas no geral não é realmente que caro apenas para executar todas as verificações.
fonte
Você pode fazer mãos de pôquer de maneira relativamente fácil com uma abordagem iterativa simples.
Para cada carta, verifique se há uma ou duas ou três outras com a mesma face para verificar o par ou três / quatro do mesmo tipo.
Casas cheias são semelhantes. Ou se você encontrar um par e três do mesmo tipo que não sejam da mesma face, marque uma casa cheia como encontrada.
Para flushs, verifique cada naipe para ver se há cinco da mesma naipe.
Verificar diretamente é fácil, mesmo que não classificado. Para cada cartão, verifique se existe um mais alto e repita até que cinco cartões consecutivos sejam encontrados ou não.
Royal flushes e straight flushes podem ser encontrados da mesma forma que os straights. Royal flushes têm algumas condições extras, pois cartões de menor valor podem ser ignorados.
Sim, essa abordagem é ineficiente, mas para a maioria dos jogos de poker isso é irrelevante. Você está checando um punhado de jogadores a cada meio minuto, não checando milhares de mãos por segundo.
Existem métodos melhores, mas podem levar mais tempo para codificar, e você provavelmente tem coisas mais importantes para gastar tempo / dinheiro, o que contribuirá para um jogo melhor da perspectiva dos jogadores, além da esperteza e eficiência de um algoritmo.
fonte
Uma maneira simples de encontrar pares, pares duplos, toaks, casas completas, jogadores de pôquer etc. é a seguinte:
compare cada cartão um com o outro em um loop aninhado como este:
As partidas terão o seguinte:
2 para um par
4 para dois pares
6 para toak
8 para uma casa cheia
12 para um pôquer
para otimizar rapidamente isso: não é necessário executar o loop j até 5, ele pode ser executado no i-1. a comparação "i! = j" pode ser removida e os valores da correspondência são divididos pela metade (1 = par, 2 = 2 pares etc.)
fonte