Проверка покерных рук

У меня были некоторые проблемы с проверкой покерных рук. Таким образом, в этом коде мы выбираем, с какими колодами мы хотим играть, а остальное похоже на видеопокер. Моя проблема в том, что некоторые из проверенных рук "видны". Для прямой, я предполагаю, потому что у меня это установлено, как будто мой 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 в вашем nbPerRankint массив.

Псевдокод может быть таким:

// 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, которые вы ей передали?

Другие вопросы по тегам