2009-08-20 7 views
1

Zur Zeit versuche ich zu portieren Keith Rule Texas Holdem Hand Evaluator nach Omaha Hallo:Omaha Hallo Hand Evaluator

Nach mehr über das Denken Algorithmus, fand ich eine Lösung, die mir die richtigen Prozentsätze für die Hände gibt und alles in Ordnung ist.

Aber es ist wirklich sehr langsam. Wie kann ich die Dinge beschleunigen?

Als einzige Sache, die ich gerade mache, ist eine normale Fünf-Karten-Hände zu suchen, eine LUT könnte für mich richtig sein. Wer hat schon mal einen integriert?

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

Antwort

3

Sieht aus, als ob Sie versuchen, Equity-Rechner zu erstellen. Ich habe das auch gemacht, aber nicht für Omaha (Texas Hold'em statt). Mit den dann zu bewertenden Spielern habe ich ~ 200K Hände pro Sekunde, was in kürzester Zeit ein genaues Ergebnis liefert. Wenn dort nur zwei Spieler auswerten, kann ich bis zu 4 Millionen Auswertungen pro Sekunde bekommen.

Ich benutzte Bitmasken für die Hände. Eine 64-Bit-Ganzzahl zur Darstellung von Karte, Hand oder ganzer Karte. Sie brauchen nur 52 davon, offensichtlich. Durch den Einsatz von Bitwise-Operatoren kommen die Dinge ziemlich schnell voran. Hier ist eine kurze Probe von meinem Projekt (in C++ tho). Es wird mit 2 + 2 Auswerter für schnelle Look-ups:


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

Bitte beachten Sie die 2 + 2 Auswerter, die ganz einfach in Ihren eigenen Bedürfnissen anzupassen.

1

helfen Dies könnte:

Ein Beispiel eines fertig Objective-C (und Java) Texas Hold'em 7- und 5-Karten-Auswerter here gemacht und weiter erklärt here gefunden werden kann. Es "addiert" Hände, um einen Index zu erzeugen, der die Hand zur Bestimmung des Rangs ausreichend kennzeichnet.

Alle Bewertungen sind willkommen unter der E-Mail-Adresse