Омаха Привет Рука Оценщик - PullRequest
       37

Омаха Привет Рука Оценщик

1 голос
/ 20 августа 2009

В настоящее время я пытаюсь перенести техасский холдем-оценщик Кейта Рула в Омаху. Привет:

Подумав больше об алгоритме, я нашел решение, которое дает мне правильные проценты для рук, и все в порядке ..

Но это действительно очень медленно. Как я могу ускорить процесс?

Поскольку единственное, что я сейчас делаю, - это поиск нормальных пятикарточных рук, LUT может быть для меня подходящим. Кто-нибудь раньше интегрировал?

static void Main(string[] args)
    {
        long count = 0;
        double player1win = 0.0, player2win=0.0;
        ulong player1 = Hand.ParseHand("Ad Kd As Ks");
        ulong player2 = Hand.ParseHand("Th 5c 2c 7d");
        foreach (ulong board in Hand.Hands(0, player1 | player2, 5))
        {
            uint maxplayer1value = 0, maxplayer2value = 0;
            foreach (ulong boardcards in Hand.Hands(0, ulong.MaxValue ^ board, 3))
            {
                foreach (ulong player1hand in Hand.Hands(0Ul, ulong.MaxValue ^ player1, 2))
                {
                    uint player1value = Hand.Evaluate(player1hand | boardcards, 5);
                    if (player1value > maxplayer1value) maxplayer1value = player1value;

                }
            }
            foreach (ulong boardcards in Hand.Hands(0, ulong.MaxValue ^ board, 3))
            {
                foreach (ulong player2hand in Hand.Hands(0UL, ulong.MaxValue ^ player2, 2))
                {
                    uint player2value = Hand.Evaluate(player2hand | boardcards, 5);
                    if (player2value > maxplayer2value) maxplayer2value = player2value;

                }
            }

            if (maxplayer1value > maxplayer2value)
            {
                player1win += 1.0;
            }
            else if (maxplayer2value > maxplayer1value)
            {
                player2win += 1.0;
            }
            else
            {
                player1win += 0.5;
                player2win += 0.5;
            }
            count++;
        }
        Console.WriteLine("Player1: {0:0.0000} Player2: {1:0.0000} Count: {2}", player1win / count * 100, player2win / count * 100, count);
        Console.ReadLine();       
    }

Ответы [ 2 ]

3 голосов
/ 18 сентября 2009

Похоже, вы пытаетесь создать калькулятор капитала. Я тоже так делал, но не для Омахи (вместо этого Техасский Холдем). С учетом того, что игроки могли оценить, у меня есть ~ 200K рук в секунду, что дает достаточно точный результат в кратчайшие сроки. Если там только два игрока оценивать, я могу получить до 4 миллионов оценок в секунду.

Я использовал битовые маски для рук. Одно 64-разрядное целое число для представления карты, руки или всей доски. Вам нужно всего лишь 52 из этого, очевидно. Используя побитовые операторы, дела идут довольно быстро. Вот быстрый пример из моего проекта (на C ++, хотя). Это использует 2 + 2 оценщика для быстрого поиска:


        while (trial < trials) {
                /** I use here a linked list over the hand-distributions (players).
                  * This is kind of natural as well, as circle is the basic
                  * shape of poker.
                  */
                pDist = pFirstDist;

                unsigned __int64 usedCards = _deadCards;
                bool collision;

                /** Here, we choose random distributions for the comparison.
                  * There is a chance, that two separate distributions has
                  * the same card being picked-up. In that case, we have a collision,
                  * so do the choosing again.
                  */
                do {
                        pDist->Choose(usedCards, collision);

                        /** If there is only one hand in the distribution (unary),
                          * there is no need to check over collision, since it's been
                          * already done in the phase building them (distributions).
                          */
                        if (pDist->_isUnary)
                                collision = false;

                        pDist = pDist->_pNext;
                } while (pDist != pFirstDist && !collision);

                if (collision) {
                        /** Oops! Collision occurred! Take the next player (hand-
                          * distribution and do this all over again.
                          *
                          */
                        pFirstDist = pDist->_pNext;

                        continue;
                }

                unsigned __int64 board = 0;

                /** Pick a board from the hashed ones, until it's unique compared to
                  * the distributions.
                  *
                  */
                do {
                        if (count == 1) {
                                board = boards[0];
                                collision = false;
                        } else {
                                board = boards[Random()];
                                collision = (board & usedCards) != 0;
                        }
                } while (collision);

                board |= _boardCards;

                int best = 0, s = 1;

                do {
                        pDist->_currentHand |= board;

                        unsigned long i, l = static_cast<unsigned long>(pDist->_currentHand >> 32);
                        int p;
                        bool f = false;

                        /** My solution to find out the set bits.
                          * Since I'm working on a 32-bit environment, the "64-bit"
                          * variable needs to be split in to parts.
                          */
                        if (_BitScanForward(&i, l)) {
                                p = _evaluator->_handRanks[53 + i + 32]; // Initial entry to the 2 + 2 evaluator hash.
                                l &= ~(static_cast<unsigned long>(1) << i);
                                f = true;
                        }

                        if (f)
                                while (_BitScanForward(&i, l)) {
                                        l &= ~(static_cast<unsigned long>(1) << i);
                                        p = _evaluator->_handRanks[p + i + 32];
                                }

                        l = static_cast<unsigned long>(pDist->_currentHand & 0xffffffff);

                        if (!f) {
                                _BitScanForward(&i, l);

                                p = _evaluator->_handRanks[53 + i];
                                l &= ~(static_cast<unsigned long>(1) << i);
                        }

                        while (_BitScanForward(&i, l)) {
                                l &= ~(static_cast<unsigned long>(1) <<_handRanks[p + i];
                        }

                        pDist->_rank = p;

                        /** Keep the statistics up. Please do remember, that
                          * equity consist of ties as well, so it's not a percentual
                          * chance of winning.
                          */
                        if (p > best) {
                                pWinner = pDist;
                                s = 1;
                                best = p;
                        } else if (p == best)
                                ++s;

                        pDist = pDist->_pNext;
                } while (pDist != pFirstDist);

                if (s > 1) {
                        for (unsigned int i = 0; i _rank == best) {
                                        _handDistributions[i]->_ties += 1.0f / s;
                                        _handDistributions[i]->_equity += 1.0f / s;
                                }
                } else {
                        ++pWinner->_wins;
                        ++pWinner->_equity;
                }

                ++trial;

                pFirstDist = pDist->_pNext;
        }

Пожалуйста, обратитесь к оценщику 2 + 2, который довольно легко адаптировать к вашим собственным потребностям.

1 голос
/ 13 апреля 2011

Это может помочь:

Пример готового Objective-C (и Java) Texas Hold'em с 7- и 5-карточным оценщиком можно найти здесь и более подробно объяснить здесь . Он «складывает» руки для создания индекса, который достаточно характеризует руку для определения ранга.

Все отзывы приветствуются по адресу электронной почты, найденному там

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...