Regex para calcular a mão direta do poker?
Pergunta
Existe uma regex para calcular a mão direta do poker?
Estou usando strings para representar os cartões classificados, como:
AAAAK#sssss = 4 aces and a king, all of spades.
A2345#ddddd = straight flush, all of diamonds.
Em Java, estou usando estas regexes:
regexPair = Pattern.compile(".*(\\w)\\1.*#.*");
regexTwoPair = Pattern.compile(".*(\\w)\\1.*(\\w)\\2.*#.*");
regexThree = Pattern.compile(".*(\\w)\\1\\1.*#.*");
regexFour = Pattern.compile(".*(\\w)\\1{3}.*#.*");
regexFullHouse = Pattern.compile("((\\w)\\2\\2(\\w)\\3|(\\w)\\4(\\w)\\5\\5)#.*");
regexFlush = Pattern.compile(".*#(\\w)\\1{4}");
Como calcular valores retos (sequências) com regex?
EDITAR
Abro outra pergunta para resolver o mesmo problema, mas usando o valor ASCII de char, para regex ser curto. Detalhes aqui.
Obrigado!
Solução
Eu tenho que admitir que expressões regulares não são a primeira ferramenta que eu teria pensado em fazer isso. Posso garantir que qualquer RE capaz de fazer isso com uma mão não classificado seja muito mais hediondo e muito menos legível que o código processual equivalente.
Supondo devo Use um regex, você poderia Use uma construção como
2345A|23456|34567|...|9TJQK|TJQKA
Para detectar a parte do valor nominal da mão.
De fato, pelo que eu recebo aqui Das mãos "padrão", o seguinte deve ser verificado em ordem de prioridade decrescente:
Royal/straight flush: "(2345A|23456|34567|...|9TJQK|TJQKA)#(\\w)\\1{4}"
Four of a kind: ".*(\\w)\\1{3}.*#.*"
Full house: "((\\w)\\2\\2(\\w)\\3|(\\w)\\4(\\w)\\5\\5)#.*"
Flush: ".*#(\\w)\\1{4}"
Straight: "(2345A|23456|34567|...|9TJQK|TJQKA)#.*"
Three of a kind: ".*(\\w)\\1\\1.*#.*"
Two pair: ".*(\\w)\\1.*(\\w)\\2.*#.*"
One pair: ".*(\\w)\\1.*#.*"
High card: (none)
Basicamente, esses são os mesmos que o seu, exceto que eu adicionei o rubor real/reto e o reto. Desde que você os verifique em ordem, você deve obter a melhor pontuação da mão. Não há regex para o cartão alto, pois, naquele momento, é a única pontuação que você pode ter.
Eu também mudei a roda de aço (envoltório) reta de A2345
para 2345A
já que eles serão classificados dessa maneira.
Outras dicas
Reescrevi o regex para isso porque achei frustrante e confuso. Os agrupamentos fazem muito mais sentido para esse tipo de lógica. A classificação está sendo feita usando um método de classificação de matriz padrão em JavaScript. Portanto, a ordem estranha dos cartões, eles estão em ordem alfabética. Eu fiz o meu em JavaScript, mas o Regex poderia ser aplicado ao Java.
hands = [
{ regex: /(2345A|23456|34567|45678|56789|6789T|789JT|89JQT|9JKQT|AJKQT)#(.)\2{4}.*/g , name: 'Straight flush' },
{ regex: /(.)\1{3}.*#.*/g , name: 'Four of a kind' },
{ regex: /((.)\2{2}(.)\3{1}#.*|(.)\4{1}(.)\5{2}#.*)/g , name: 'Full house' },
{ regex: /.*#(.)\1{4}.*/g , name: 'Flush' },
{ regex: /(2345A|23456|34567|45678|56789|6789T|789JT|89JQT|9JKQT|AJKQT)#.*/g , name: 'Straight' },
{ regex: /(.)\1{2}.*#.*/g , name: 'Three of a kind' },
{ regex: /(.)\1{1}.*(.)\2{1}.*#.*/g , name: 'Two pair' },
{ regex: /(.)\1{1}.*#.*/g , name: 'One pair' },
];