2009-08-20 11 views
1

Actuellement, je suis en train de port de Keith Règle Texas Holdem Evaluator Main à Omaha Salut:Omaha Salut main Evaluator

Après avoir réfléchi plus sur la algorithme, j'ai trouvé une solution qui me donne les bons pourcentages pour les mains et tout va bien ..

Mais c'est vraiment très lent. Comment puis-je accélérer les choses?

Comme la seule chose que je fais en ce moment est de chercher une main normale de cinq cartes, un LUT pourrait être bon pour moi. Quelqu'un a intégré un avant?

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

Répondre

3

On dirait que vous essayez de créer une calculatrice d'équité. Je l'ai fait aussi bien, mais pas pour Omaha (Texas Hold'em à la place). Avec les joueurs alors à évaluer, j'ai environ ~ 200K mains par seconde, ce qui donne un résultat précis en un rien de temps. S'il n'y a que deux joueurs à évaluer, je peux obtenir jusqu'à 4 millions d'évaluations par seconde.

J'ai utilisé des masques de bits pour les mains. Un entier de 64 bits pour représenter une carte, une main ou une carte entière. Vous n'en avez besoin que de 52, évidemment. En utilisant des opérateurs au niveau du bit, les choses se passent plutôt rapidement. Voici un exemple rapide de mon projet (en C++ tho). Il utilise l'évaluateur 2 + 2 pour un look-up rapide:


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

S'il vous plaît se référer à l'évaluateur 2 + 2, ce qui est assez facile d'adapter à vos propres besoins.

1

Cela pourrait aider:

Un exemple d'un prêt à l'emploi Objective-C (et Java) Texas Hold'em 7 et évaluateur de 5 cartes se trouve here et expliquée plus en détail here. Il "ajoute" des mains pour générer un index qui caractérise suffisamment la main pour déterminer le rang.

Tous les commentaires sont les bienvenus à l'adresse e-mail qui s'y trouve