1

現在、キースルールのテキサスホールデムハンドエバリュエーターをオマハに移植しようとしています。

アルゴリズムについてもっと考えた後、私は手に適切なパーセンテージを与え、すべてがうまくいく解決策を見つけました。

しかし、それは本当に遅いです。どうすればスピードアップできますか?

私が今しているのは通常の5枚のカードの手を調べることだけなので、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();       
    }
4

2 に答える 2

3

エクイティ計算機を作成しようとしているようです。私もこれを行いましたが、オマハ(代わりにテキサスホールデム)では行いませんでした。プレーヤーが評価することで、私は毎秒約200Kのハンドを手に入れました。これにより、すぐに十分に正確な結果が得られます。評価するプレーヤーが2人しかない場合、1秒あたり最大400万の評価を得ることができます。

手にはビットマスクを使用しました。カード、ハンド、またはボード全体を表す1つの64ビット整数。明らかに、実際に必要なのは52個だけです。ビット演算子を使用することにより、物事はかなり迅速に進みます。これが私のプロジェクトからの簡単なサンプルです(C ++ thoで)。迅速な検索のために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エバリュエーターを参照してください。

于 2009-09-18T19:37:25.583 に答える
1

これは役立つかもしれません:

既製のObjective-C(およびJava)Texas Hold'em 7および5カード評価者の例は、ここにあり、ここでさらに説明されています。ハンドを「加算」して、ランクを決定するためにハンドを十分に特徴付けるインデックスを生成します。

そこにある電子メールアドレスですべてのフィードバックを歓迎します

于 2011-04-12T23:30:58.043 に答える