Domanda

Al momento sto cercando di Texas Holdem mano valutatore del porto Keith regola per Omaha Hi:

Dopo aver riflettuto di più su l'algoritmo, ho trovato una soluzione che mi dà le percentuali giuste per le mani e tutto va bene ..

Ma è davvero molto lento. Come posso accelerare le cose?

Come l'unica cosa che faccio in questo momento è quello di look-up di una normale carta di cinque mani, una LUT potrebbe essere giusto per me. Chiunque uno integrato prima?

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();       
    }
È stato utile?

Soluzione

Sembra che si sta cercando di creare calcolatrice equità. Ho fatto anche questo, ma non per Omaha (Texas Hold'em, invece). Con l'allora ai giocatori di valutare, Ho circa ~ 200K mani al secondo, che dà risultati accurati abbastanza in pochissimo tempo. ci Se solo due giocatori valutare, posso avere fino a 4 milioni di valutazioni al secondo.

Ho usato maschere di bit per le mani. Un intero a 64 bit per rappresentare carta, a mano o intera scheda. Hai solo bisogno in realtà 52 di esso, ovviamente. Utilizzando bit a bit-operatori, le cose si fanno andare piuttosto rapidamente. Ecco un rapido esempio dal mio progetto (in C ++ tho). E 'con 2 + 2 valutatore per veloci look-up:


        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;
        }

Si prega di fare riferimento alla 2 + 2 valutatore, che è abbastanza facile da adattare a proprie esigenze.

Altri suggerimenti

Questo potrebbe aiutare:

Un esempio di un ready made Objective-C (e Java) Texas Hold'em valutatore 7 e 5-card può essere trovato qui e inoltre spiegato qui . It "aggiunge" le mani per generare un indice che caratterizza sufficientemente la mano per determinare rango.

Tutte le valutazioni di benvenuto presso l'indirizzo di posta elettronica ivi contenute

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top