Проверка покерных рук
У меня были некоторые проблемы с проверкой покерных рук. Таким образом, в этом коде мы выбираем, с какими колодами мы хотим играть, а остальное похоже на видеопокер. Моя проблема в том, что некоторые из проверенных рук "видны". Для прямой, я предполагаю, потому что у меня это установлено, как будто мой arraylist отсортирован по предположению, как бы я это исправить?
Также, что касается двух пар, мой друг сказал, что несколько раз он не будет правильно проверять, действительно ли у меня есть две пары, говоря, что это не проверяет правильно. Вот мои алгоритмы проверки, может кто-нибудь сказать мне, как их исправить? Кроме того, если есть какие-либо проблемы, которые вы видите, кроме прямой и двух пар, имеющих проблемы. Я еще не прошел фулл-хаус или больше, чтобы проверить..Get(#) получает карточную масть или ранг (гетту или гетранк) из моей руки (arraylist). Я также думаю, что мой флеш-рояль может быть неправильным.
private boolean flush(){
if (currentHand.get(0).getSuit() == currentHand.get(1).getSuit()
&& currentHand.get(1).getSuit() == currentHand.get(2).getSuit()
&& currentHand.get(2).getSuit() == currentHand.get(3).getSuit()
&& currentHand.get(3).getSuit() == currentHand.get(4).getSuit()){
return true;
}
return false;
}
private boolean royal(){
if ((currentHand.get(0).getRank() == 1)
&& (currentHand.get(1).getRank() == 10)
&& (currentHand.get(2).getRank() == 11)
&& (currentHand.get(3).getRank() == 12)
&& (currentHand.get(4).getRank() == 13)) {
return true;
}
return false;
}
private boolean straight(){//look up
if (currentHand.get(0).getRank() + 1 == currentHand.get(1).getRank()
&& currentHand.get(1).getRank() + 1 == currentHand.get(2).getRank()
&& currentHand.get(2).getRank() + 1 == currentHand.get(3).getRank()
&& currentHand.get(3).getRank() + 1 == currentHand.get(4).getRank()) {
return true;
}
return false;
}
private boolean four(){
if (currentHand.get(0).getRank() == currentHand.get(1).getRank()
&& currentHand.get(1).getRank() == currentHand.get(2).getRank()
&& currentHand.get(2).getRank() == currentHand.get(3).getRank()) {
return true;
} else if (currentHand.get(1).getRank() == currentHand.get(2).getRank()
&& currentHand.get(2).getRank() == currentHand.get(3).getRank()
&& currentHand.get(3).getRank() == currentHand.get(4).getRank()) {
return true;
}
return false;
}
private boolean fullHouse() {
if (currentHand.get(0).getRank() == currentHand.get(1).getRank()
&& currentHand.get(1).getRank() == currentHand.get(2).getRank()) {
if (currentHand.get(3).getRank() == currentHand.get(4).getRank()) {
return true;
}
}else if(currentHand.get(0).getRank() == currentHand.get(1).getRank()){
if(currentHand.get(2).getRank() == currentHand.get(3).getRank()
&& currentHand.get(3).getRank() == currentHand.get(4).getRank()){
return true;
}
}
return false;
}
private boolean threeOfKind(){
if ((currentHand.get(0).getRank() == currentHand.get(1).getRank()
&& currentHand.get(1).getRank() == currentHand.get(2).getRank())
|| (currentHand.get(1).getRank() == currentHand.get(2).getRank()
&& currentHand.get(2).getRank() == currentHand.get(3).getRank())
|| (currentHand.get(2).getRank() == currentHand.get(3).getRank()
&& currentHand.get(3).getRank() == currentHand.get(4).getRank())){
return true;
}
return false;
}
private boolean twoPair() {
if (currentHand.get(0).getRank() == currentHand.get(1).getRank()
&& currentHand.get(2).getRank() == currentHand.get(3).getRank()){
return true;
}
else if((currentHand.get(1).getRank() == currentHand.get(2).getRank())&&
(currentHand.get(3).getRank() == currentHand.get(4).getRank())){
return true;
}
else if((currentHand.get(0).getRank() == currentHand.get(1).getRank())&&
(currentHand.get(3).getRank() == currentHand.get(4).getRank())){
return true;
}else
return false;
}
private boolean jackOrBetter() {
for (int i = 11; i <= 14; i++) {
int comp;
if (i == 14)
comp =1;
else comp = i;
for (int j = 0; j < 4; j++) {
if (currentHand.get(j).getRank() ==comp ) {
if (currentHand.get(j).getRank() == currentHand.get(j + 1).getRank()) {
return true;
}
}
}
}
return false;
1 ответ
Как правило, код, который вы найдете в известных (и очень быстрых) покерных оценщиках, гораздо более низкого уровня, чем этот: никакой необычной ОО или чего-то подобного. Просто быстрые манипуляции с битами и сумасшедшие, сумасшедшие быстрые поиски за столом. Оценщики быстрых рук могут оценивать сотни миллионов (!) Рук... в секунду! Но давайте оставим это в стороне и начнем с вашего OOish кода.
Я так понимаю, вам нужен оценщик из пяти карт, а затем, если вы играете, скажем, в Техасский Холдем, вы собираетесь протестировать C(7,5), что дает 21 возможный способ взять 5 карт из семи (5 на доске + 2 закрытые карты). И держи лучшую руку.
Итак, к вашему пятикарточному оценщику.
"Уловка" упрощает вашу работу, сохраняя промежуточную информацию. Ваша логика тогда сильно упрощается.
Вот один из способов, которым вы могли бы это сделать (еще раз: это слишком упрощение по сравнению с очень быстрыми оценщиками, но это должно помочь вам выполнить работу):
final boolean isFlush = flush();
final int[] nbPerRank = findNumberForEachRank();
final boolean isStraight = straight( nbPerRank );
Где nbPerRank
скажем, массив для "полных пяти королев" (три королевы и две пятерки) может выглядеть так:
; 2 3 4 5 6 7 8 9 T J Q K A
int[] nbPerRank = [ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0 ]
Тогда ваш основной метод должен выглядеть примерно так:
if ( isStraight ) {
final int highCard = findStraightHighCard();
if ( isFlush ) {
if ( highCard == 13 ) { // starting with the 'A'
System.out.println( "You have a royal flush" );
else if ( highCard = 4 ) { // starting with the '5'
System.out.println( "You have a wheel straight flush" );
} else {
System.out.println( "You have a straight flush " );
}
} else {
... // rinse and repeat for normal straight
}
} else {
...
Обратите внимание на то, что ваш оценщик является оценщиком из 5 карт, и если у вас есть стрит, вы знаете, что есть только два возможных случая: стрит-стрит-флеш (с пятью картами невозможно получить даже пару, если у вас уже есть стрит с эти пять карт).
Таким образом, к настоящему моменту вы уже приняли во внимание стрит-флеш и стрит, теперь вам нужно проверить, чтобы:
- четверка
- полный дом / лодка
- флеш (но больше не флеш)
- задавать
- две пары
- одна пара
Чтобы проверить, есть ли у вас четыре вида, посмотрите, есть ли у вас номер 4 в вашем nbPerRank
int
массив.
Псевдокод может быть таким:
// no need to test for straight an straight flush anymore...
if ( hasFourSameRank ) {
" You have four of a kind ";
} else if ( hasThreeSameRank && hasTwoSameRank ) {
" You have a full house ";
} else if ( isFlush ) {
" You have a flush";
} else if ( hasThreeSameRank ) {
" You have a set ";
} else if ( hasTwoSameRank ) {
// two possible cases here: two pairs or one pair
if ( hasTwoPairs ) {
"You have two pairs";
} else {
"You have one pair";
} else {
"You have no pair";
}
Вложенные if / else вполне нормальны в таких оценщиках (по крайней мере, в тех, которые не используют таблицы поиска / LUT).
Обратите внимание, что это только один из способов сделать это. Вы можете пойти "любитель" и вместо того, чтобы просто возвращать int[], содержащее номер каждой карты за ранг, вы также можете вернуть максимальное количество карт, максимальное количество аналогичных рангов и т. Д.
Затем вам нужно будет найти способ назначить значение (отсюда и название "оценщика") для каждой руки, так что "две пары, восьмерки и двойки, киккер джек" бьет "две пары, восьмерки и двойки, кикер девять" и т.п.
Но это должно помочь вам начать.
Другое решение состоит в том, чтобы просто повторно использовать один из существующих оценщиков (который, в дополнение к проверке и тестированию, должен быть очень быстрым: это только битовые манипуляции и таблицы поиска, а не медленный OO).
(немного связано), вы также можете прочитать мой старый ответ здесь: на Two Plus Two покерный покер, как вы получаете лучшую комбинацию из 5 карт из 7, которые вы ей передали?