2009-08-20 9 views
1

現在、私は、オマハHiにポートキース・ルールのテキサスホールデムのハンド評価者にしようとしている:オマハこんにちはハンド評価者

についてもっと考えた後、アルゴリズム、私は私に手のための適切なパーセンテージを与えるソリューションを見つけた、すべてが正常です..

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

私が今行っている唯一のことは、通常の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();  
    } 

答えて

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評価 を使用しています。

1

これは役立つかもしれない:

既製のObjective-C(とJava)の一例をテキサスホールデム7と5枚のカードの評価者がhereを発見し、さらにhereを説明することができます。ランクを決定するために手を十分に特徴付ける指数を生成するために手を上げる。

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