Image Image Image




Post new topic Reply to topic  [ 399 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 20  Next
Author Message
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sun Mar 30, 2008 10:53 pm 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
Can you attach to the thread a C++ evaluator of RayW, with a simple example?

Hi,
Here are the modifications I had to make to compile it under Visual Studio C++ (it uses also Paul Senzee's modification of Cactus Kev's code).
The original code is in this link: http://archives1.twoplustwo.com/showthr ... age=0&vc=1 (remember to change the line that matters only for Java porting).
At the end is also the example, that is the standard benchmark that was used in the 2+2 thread (saving partial states).
Regards ...
BTW, I'm not involved in Poker Bots, just in case someone from the sites I play in notice this post.

So now, the modifications.

In File: HandRankSetup.cpp

Line 4
Replace
Code:
   #include "stdafx.h"
With
Code:
   // #include "stdafx.h"
   #include <stdio.h>  // Required for FILE, printf, fout, fopen, fwrite, fclose
   #include <Tchar.h>  // Required for_TCHAR
In File: HandRankSetup.cpp
Add
Code:
#define srand48 srand      // Definition of srand48 (http://www-teaching.physics.ox.ac.uk/computing/Downloads/downloads.html). Added to prevent "allfive.c(22) : warning C4013: 'srand48' undefined; assuming extern returning int" and "allfive.obj : error LNK2019: unresolved external symbol _srand48 referenced in function _main"

// Definition of drand48 (http://www-teaching.physics.ox.ac.uk/computing/Downloads/downloads.html)
// Added to prevent "pokerlib.obj : error LNK2019: unresolved external symbol _drand48 referenced in function _shuffle_deck"
double drand48(void)
{
  double random_number;

  random_number=rand()/(double)RAND_MAX;
  return random_number;
}

In File: poker.h
Replace at the end
Code:
    init_deck( int *deck );         // Added to prevent warning C4013: 'init_deck' undefined; assuming extern returning int
  int  hand_rank( short val );         // Added to prevent warning warning C4013: 'hand_rank' undefined; assuming extern returning int
  short eval_5hand( int *hand );        // Added to prevent warning C4013: 'hand_rank' undefined; assuming extern returning int
  int eval_5hand_fast(int c1, int c2, int c3, int c4, int c5); // Added to prevent warning C4013: 'eval_5hand_fast' undefined; assuming extern returning int

With
Code:
  #ifdef __cplusplus
  extern "C" {
  #endif

  int  init_deck( int *deck );         // Added to prevent warning C4013: 'init_deck' undefined; assuming extern returning int
  int  hand_rank( short val );         // Added to prevent warning warning C4013: 'hand_rank' undefined; assuming extern returning int
  short eval_5hand( int *hand );        // Added to prevent warning C4013: 'hand_rank' undefined; assuming extern returning int
  int eval_5hand_fast(int c1, int c2, int c3, int c4, int c5); // Added to prevent warning C4013: 'eval_5hand_fast' undefined; assuming extern returning int

  short eval_5cards( int c1, int c2, int c3, int c4, int c5 ); // Added to prevent error C3861: 'eval_5cards': identifier not found
  short eval_7hand( int *hand );        // Added to prevent error C3861: 'eval_7hand': identifier not found

  #ifdef __cplusplus
  }
  #endif

And the example is at the end of the HandRankSetup.cpp file:

Code:
   timer = clock();   // now get current time for Testing! 

   // another algorithm right off the thread

   int c0, c1, c2, c3, c4, c5, c6;
   int u0, u1, u2, u3, u4, u5;

   QueryPerformanceCounter(&timings);                // start High Precision clock

   for (c0 = 1; c0 < 53; c0++) {
      u0 = HR[53+c0];
      for (c1 = c0+1; c1 < 53; c1++) {
         u1 = HR[u0+c1];
         for (c2 = c1+1; c2 < 53; c2++) {
            u2 = HR[u1+c2];
            for (c3 = c2+1; c3 < 53; c3++) {
               u3 = HR[u2+c3];
               for (c4 = c3+1; c4 < 53; c4++) {
                  u4 = HR[u3+c4];
                  for (c5 = c4+1; c5 < 53; c5++) {
                     u5 = HR[u4+c5];
                     for (c6 = c5+1; c6 < 53; c6++) {
                        handTypeSum[HR[u5+c6] >> 12]++;
                        count++;
                     }
                  }
               }
            }
         }
      }
   }
   
   QueryPerformanceCounter(&endtimings);     // end the high precision clock

   timer = clock() - timer;  // get the time in this

   for (int i = 0; i <= 9; i++)  // display the results
      printf("\n%16s = %d", HandRanks[i], handTypeSum[i]);
   
   printf("\nTotal Hands = %d\n", count);
   
   __int64 clocksused = (__int64)endtimings.QuadPart - (__int64) timings.QuadPart;  // calc clocks used from the High Precision clock

   // and display the clock results
   printf("\nValidation seconds = %.4lf\nTotal HighPrecision Clocks = %I64d\nHighPrecision clocks per lookup = %lf\n", (double)timer/CLOCKS_PER_SEC, clocksused, (double) clocksused /  133784560.0) ;


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sun Mar 30, 2008 11:23 pm 
Offline
Senior member
User avatar

Posts: 465
Favourite Bot: Mine, of course!
There is a new build of a C# .Net hand evaluator at http://www.codeproject.com/KB/game/MoreTexasHoldemAnalysis2.aspx. It takes advantage of multiple processors (dual core). I tried it an it is very fast, although I have it restricted to a single processor. Calculating Raw ExHS for a hand on the flop comes back almost instaneously; certainly less than half a second. I haven't put together a timer test yet. Looking at the graphic at the top of the web page, it seems to be boasting over 170 million hands / second. It doesn't say what machine that screen shot was taken from though.

There were two previous releases. You may want to read through the whole thing:
http://www.codeproject.com/KB/game/pokerhandevaldoc.aspx First relase
http://www.codeproject.com/KB/game/MoreTexasHoldemAnalysis1.aspx Second release
http://www.codeproject.com/KB/game/MoreTexasHoldemAnalysis2.aspx Latest release (uses multiple processors)

I didn't like the multi-core demo, because it nailed both my processors to 100%; although if the calc is less than a second I guess it doesn't matter.


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sun Mar 30, 2008 11:39 pm 
Offline
PokerAI fellow
User avatar

Posts: 686
Location: Midwest, USA
Favourite Bot: N/A
Adrian20XX, is there any chance I could get you to drop the code in a zip file and upload it? It'd be much appreciated. Thanks.


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sun Mar 30, 2008 11:44 pm 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
Timmy wrote:
Adrian20XX, is there any chance I could get you to drop the code in a zip file and upload it? It'd be much appreciated. Thanks.

Sure, but you have to let me know how to upload the file in here, I don't see the option.
Anyway, it's pretty easy to compile it with the modifications I've posted here.
Regards ...


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sun Mar 30, 2008 11:53 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Adrian20XX wrote:
Sure, but you have to let me know how to upload the file in here, I don't see the option.
Anyway, it's pretty easy to compile it with the modifications I've posted here.
Regards ...


Image

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 12:52 am 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
OK, here it is.
Regards ...


Attachments:
File comment: Ray W's code, with Paul Senzee's evaluator built from Cactus Kev's code. Hyper ultra minor modifications made to compile by Adrian
RayW.zip [65.41 KB]
Downloaded 233 times
Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 1:08 am 
Offline
PokerAI fellow
User avatar

Posts: 686
Location: Midwest, USA
Favourite Bot: N/A
Alright, thank you for uploading it. I had to define __min to get it to compile for me, but otherwise it worked great.

I had tried to get this to compile before, but gave up after a while (I wasn't even sure what files I needed :cry: ). So thanks for making it accessible and easy.


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 5:18 am 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
There is also one C evaluator in there (my personal translated to C for the purpsoe of comparing C vs Java). You can have a look at what it is currently benchmarking and even post an integrated test would be even better.

Hi Indiana, I've just compiled your so called C evaluator under Visual Studio C++, it is not valid C language, it's actually C++ (as a C program it gives more than 100 errors, mostly because a lot of variables are declared at improper places).
You also have to return in C++ values for two functions, otherwise you get an error in C++ with Visual Studio.
handeval.cpp(135) : error C4716: 'initialize' : must return a value
handeval.cpp(184) : error C4716: 'testPokerEval' : must return a value

But, the important part is that it is evaluating:
Poker Eval Test
49353408 Hands in 30.215727 seconds
--- Hands per second: 1633368.250000
Only 1.6 million hands per second against 208 millions for RayW on my machine.

I think your cards are 0..51, ordered by suits first, right? (like 2c 2d 2h 2s 3c ..., or Ac Ad Ah As Ac ...). I can not easily see if they start with Aces or with Deuces.

The benchmark you are using seems a bit odd to me, is it evaluating X suit 0, Y suit 1, Z suit 2, T suit 3, U suit 1, V suit 2, W suit 3? (where there can be repeated suits X, Y, Z, T, U, V, W, but not five of them?).

The benchmark also is doing a bit extra work than the 2+2, comparing in the middle h4!=h1, h5!=h2 and h7!=h3 (btw, I think you wanted to do here h5!=h1, h6!=h2, h7!=3, may be??? Otherwise you can move two of these comparisons one loop out), and also incrementing the counter n.

And also you are doing less work because you seem to be only incrementing one counter with the hand value, while the 2+2 benchmark is also evaluating the hand type for each hand (and is incrementing only the number of hand types).

The 2+2 benchmark is the same conceptually that Cactus Kev's and Paul Senzee's benchmark (only that it is for 7 cards). Why did you opted for this benchmark instead of the existing one?

Regards ...


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 7:35 am 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Yes, it's C++. I'll change that. Cards encoding (for my personal hand evaluator, i.e. in the C++ example in the archive) is as you suggest (se below).

So you got 208m hands with this benchmark? I will doublecheck that in the next days.

Why this benchmark: In short, I did this benchmark in a haste. To fix it was one of the biggest todo since the beginning, but I never did it, as adopting and looking at the "next" evalautor was always more interesting, and keeping a running version of every ealuator was a guarantee that at any point of time I can get back to this and retest. I will also look into this.

I'm thinking to go for:
* OK, first undertsand the differences between Cactus Kev's / Paul Senzee's / 2+2 and mine. To be honest I did mine so long ago, that I have now to understand what it is doing in the same way as for the rest (I never documented it)
* Develop some "random" hand sequence test, i.e. heavily unordered test
* Develop and compare few practical situations, either 3 way matchup, or EHS/EHS2 and measure the differences based on which hand evaluator is used.


Code:
 
  // CARDS:
  //  0,  1,  2,  3 - 2c 2d 2s 2h
  //  4,  5,  6,  7 - 3c 3d 3s 3h
  //  8,  9, 10, 11 - 4c 4d 4s 4h
  // 12, 13, 14, 15 - 5
  // 16, 17, 18, 19 - 6
  // 20, 21, 22, 23 - 7
  // 24, 25, 26, 27 - 8
  // 28, 29, 30, 31 - 9
  // 32, 33, 34, 35 - T
  // 36, 37, 38, 39 - Jc Jd Js Jh
  // 40, 41, 42, 43 - Qc Qd Qs Qh
  // 44, 45, 46, 47 - Kc Kd Ks Kh
  // 48, 49, 50, 51 - Ac Ad As Ah

  public static int getCard(char c1, char c2) {
    //todo: make use of getRank and getSuit
    int size = 0, suit = 0;
    switch (c1) {
      case '2': size = 0; break;
      case '3': size = 1; break;
      case '4': size = 2; break;
      case '5': size = 3; break;
      case '6': size = 4; break;
      case '7': size = 5; break;
      case '8': size = 6; break;
      case '9': size = 7; break;
      case 'T': size = 8; break;
      case 'J': size = 9; break;
      case 'Q': size = 10; break;
      case 'K': size = 11; break;
      case 'A': size = 12; break;
    }
    switch (c2) {
      case 'c': suit = 0; break;
      case 'd': suit = 1; break;
      case 's': suit = 2; break;
      case 'h': suit = 3; break;
    }
    return size*4 + suit;
  }


_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 5:29 pm 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
So you got 208m hands with this benchmark? I will doublecheck that in the next days.

I got 208 million hands with the standard benchmark used in 2+2.
Your benchmark has also some extra overhead, the overhead of the multiplications and additions that are required in order to get the cards from the ranks and suits.
Plus, your solution (i.e. your algorithm) requires an extra overhead that is copying the cards, cause your evaluator is not a "pure function", it modifies the content of the parameters (i.e. the cards array) by sorting them.
Plus, you are not calculating the hand types from the hand values, that's an advantage you get.

At the end is the modification of your code that will do something closer to the 2+2 benchmark with your code (but is not evaluating the hand type from the hand value).
Your code takes 70.685 seconds to do the almost 2+2 benchmark, against the 0.642 seconds that is doing the LUT solution by RayW.
I moved out the declaration of h1 ... h7, just in case it takes an extra overhead to allocate the variables in each iteration.
indiana wrote:
I'm thinking to go for:
* OK, first undertsand the differences between Cactus Kev's / Paul Senzee's / 2+2 and mine. To be honest I did mine so long ago, that I have now to understand what it is doing in the same way as for the rest (I never documented it)

I don't think you'll gain much value in this path, I think it is better for you to start by understanding RayW's code and compiling it, with the standard 2+2 benchmark (that is also the benchmark used by Cactus Kev and Paul Senzee), and then you can develop additional benchmarks that are better suited for your scenario. You can also check first Steve Brecher's benchmark on the 2+2 thread for random hands.

BTW, is SteveBrecher now a member of Level 2b? I'm kidding, it's just that you praise his evaluator so much :-)

There are also some other LUT solutions that have been implemented but not published, one by mykey1961, one from Darse Billings that explained in a post, one from D&L (I think it was posted almost complete).

Regards ...


Code:
   int h1, h2, h3, h4, h5, h6, h7;

    for (h1 = 0; h1 < 52; h1++)
      for (h2 = h1+1; h2 < 52; h2++)
        for (h3 = h2+1; h3 < 52; h3++)
          for (h4 = h3+1; h4 < 52; h4++)
            for (h5 = h4+1; h5 < 52; h5++)
              for (h6 = h5+1; h6 < 52; h6++)
                for (h7 = h6+1; h7 < 52; h7++)
                                        {
                                hand[0] = h1;
                                hand[1] = h2;
                                hand[2] = h3;
                                hand[3] = h4;
                                hand[4] = h5;
                                hand[5] = h6;
                                hand[6] = h7;
                                sum += defineHand(hand, 7);
                                          //printf("%ld \n", ss);
                                        }

   printf("%ld\n", sum);
    float totalTime = (time() - startTime);
    float handsPerSec = 133784560 / totalTime;
    printf("Poker Eval Test\n");
    printf("%ld hands in %f seconds\n", 133784560, totalTime);
    printf(" --- Hands per second: %f \n\n", handsPerSec);


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 10:04 pm 
Offline
PokerAI fellow
User avatar

Posts: 1239
Favourite Bot: my bot
Adrian,
What is LUT?

In the RayW code there is:
Code:
   if (numcards == 6 || numcards == 7) { 
         // an extra, If you want to know what the handrank when there is 5 or 6 cards
         // you can just do HR[u3] or HR[u4] from below code for Handrank of the 5 or 6 card hand
         HR[IDnum * 53 + 53] = DoEval(IDs[IDnum]);  // this puts the above handrank into the array 
   }

Do you know how to use this? My attempt below doesn't work.

I think you can put repeated cards into the hand and it will always work, returning an InvalidHand. Is this right?

Code:
package statetableevaluator;

public class Test {
   /* Card to integer conversions:
      2c =  1    2d =  2    2h =  3    2s =  4
      3c =  5    3d =  6    3h =  7    3s =  8
      4c =  9    4d = 10    4h = 11    4s = 12
      5c = 13    5d = 14    5h = 15    5s = 16
      6c = 17    6d = 18    6h = 19    6s = 20
      7c = 21    7d = 22    7h = 23    7s = 24
      8c = 25    8d = 26    8h = 27    8s = 28
      9c = 29    9d = 30    9h = 31    9s = 32
      Tc = 33    Td = 34    Th = 35    Ts = 36
      Jc = 37    Jd = 38    Jh = 39    Js = 40
      Qc = 41    Qd = 42    Qh = 43    Qs = 44
      Kc = 45    Kd = 46    Kh = 47    Ks = 48
      Ac = 49    Ad = 50    Ah = 51    As = 52
    */
   
   
   static int[] handRanks = StateTableEvaluator.handRanks;
   static int[] c = new int[7];
   static int[] u = new int[7];
   
   static final String[] handDescriptions = {"Invalid Hand", "High Card", "One Pair", "Two Pair", "Three of a Kind",
            "Straight", "Flush", "Full House", "Four of a Kind", "Straight Flush"};
   
   public static void main(String[] args) {
      straightFlush();
      repeatedCards();
      sixCardStraightFlush(); //crashes
   }

   private static void straightFlush() {
      for (int i = 0; i < c.length; i++) {
         c[i] = 52 - 4 * i;
      }
      print(7);
   }
   
   private static void sixCardStraightFlush() {
      for (int i = 0; i < 6; i++) {
         c[i] = 52 - 4 * i;
      }
      print(6);
   }
   
   private static void repeatedCards() {
      for (int i = 0; i < c.length; i++) {
         c[i] = 52 - 4 * i;
      }
      c[6] = c[5];
      print(7);
   }

   private static void print(int l) {
      int i = 0;
      u[i] = handRanks[53 + c[i]];
      System.out.println("c[i]"  + "\t" + "u[i]");      
      System.out.println("---------------------");
      System.out.println(c[i]  + "\t" + u[i]);
      for (i = 1; i < l; i++) {
         u[i] = handRanks[u[i - 1] + c[i]];
         System.out.println(c[i]  + "\t" + u[i]);
      }
      
      System.out.println(handDescriptions[u[l - 1] >>> 12]);
      System.out.println();
   }
}


Thanks
Paul


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 10:16 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
I now did a full retest along what you posted (i.e. all possible 7-card combinations). I tested it giving the hadn with the cards in increasing and decreasing order. All results are below.

Steve Brecher is again smashing all competitors to the ground, way ahead of everyone else (just kidding, and, no, he is not a level2 member. Why I praise his evaluator so much - because I code in Java and I guess you can understand the enthusiasm one gets when his hand evaluator get ~15 times faster). Also liked it a lot because it uses very little memory, has fast initialization, and works for other viariants of poker too.

Now, it looks eventually obvious the RayW code is going to be the winner, as it is just 7 lookups in a table plus a shift right. But I would like to get this beast running in Java.

In fact, the spears port of the 2+2 code looks to me similar, if not the same as RayW code. But it has slower performance compared to SB, at least in Java. It's could be just the way the hand is encoded now. Within Ray's code there is also optimization along th way of the 7 cycles.

Quote:
Sorted test (cards are passed in increasing order h1, h2, h3, h4, h5, h6, h7)

(1) Steve Brecher HandEval, http://www.stevebrecher.com/Software/software.html
--- Hands per second: 34659212, hands 133784560, checksum 3895822421317564, total time: 3860

(2) Spears port of 2+2 evaluator, http://pokerai.org/pf3
--- Hands per second: 23783922, hands 133784560, checksum 450334402748, total time: 5625

(3) Indiana-3, 2007, http://pokerai.org/pf3
--- Hands per second: 1902700, hands 0, checksum 370104423538356, total time: 70313

(4) Indiana-1, 2006, http://pokerai.org/pf3
--- Hands per second: 1607134, hands 0, checksum 1046856166695396, total time: 83234

(5) University of Alberta, 2000, http://spaz.ca/poker
--- Hands per second: 1165716, hands 133784560, checksum 87759130835620, total time: 114766

(6) Spears port of Kevin Suffecool's C evaluator, http://pokerai.org/pf3
--- Hands per second: 874317, hands 133784560, checksum 547965983972, total time: 153016

Backward test (cards are passed in decreasing order h7, h6, h5, h4, h3, h2, h1)

(1) Steve Brecher HandEval, http://www.stevebrecher.com/Software/software.html
--- Hands per second: 35095635, hands 133784560, checksum 3895822421317564, total time: 3812

(2) Spears port of 2+2 evaluator, http://pokerai.org/pf3
--- Hands per second: 9663721, hands 133784560, checksum 450334402748, total time: 13844

(3) Indiana-3, 2007, http://pokerai.org/pf3
--- Hands per second: 1864177, hands 133784560, checksum 370104423538356, total time: 71766

(4) Indiana-1, 2006, http://pokerai.org/pf3
--- Hands per second: 1308010, hands 133784560, checksum 370104423538356, total time: 102281

(5) University of Alberta, 2000, http://spaz.ca/poker
--- Hands per second: 1176459, hands 133784560, checksum 87759130835620, total time: 113718

(6) Spears port of Kevin Suffecool's C evaluator, http://pokerai.org/pf3
--- Hands per second: 953051, hands 133784560, checksum 547965983972, total time: 140375

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 11:08 pm 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
spears wrote:
Adrian, What is LUT?

LUT = Look Up Table
spears wrote:
In the RayW code there is:
Code:
   if (numcards == 6 || numcards == 7) { 
         // an extra, If you want to know what the handrank when there is 5 or 6 cards
         // you can just do HR[u3] or HR[u4] from below code for Handrank of the 5 or 6 card hand
         HR[IDnum * 53 + 53] = DoEval(IDs[IDnum]);  // this puts the above handrank into the array 
   }

Do you know how to use this? My attempt below doesn't work.

Yes, replace the loops from the main function with this:
Code:
   for (c0 = 1; c0 < 53; c0++) {
      u0 = HR[53+c0];
      for (c1 = c0+1; c1 < 53; c1++) {
         u1 = HR[u0+c1];
         for (c2 = c1+1; c2 < 53; c2++) {
            u2 = HR[u1+c2];
            for (c3 = c2+1; c3 < 53; c3++) {
               u3 = HR[u2+c3];
               for (c4 = c3+1; c4 < 53; c4++) {
                  u4 = HR[u3+c4];
                  handTypeSum[HR[u4+0] >> 12]++;
                  count++;
//                  for (c5 = c4+1; c5 < 53; c5++) {
//                     u5 = HR[u4+c5];
//                     for (c6 = c5+1; c6 < 53; c6++) {
//                        handTypeSum[HR[u5+c6] >> 12]++;
//                        count++;
//                     }
//                  }
               }
            }
         }
      }
   }

You'll get the results from Cactus Kev:
Straight Flush 40
Four of a Kind 624
Full Houses 3744
Flush 5108
Straight 10200
Three of a Kind 54912
Two Pair 123552
One Pair 1098240
High Card 1302540
TOTAL 2598960
spears wrote:
I think you can put repeated cards into the hand and it will always work, returning an InvalidHand. Is this right?

No, not always, sometimes it returns a valid hand number.
For example if you put: c1=Ac, c2=Kc, c3=Qc, c4=Jc, C5=Tc, C6=Tc --> You get an Invalid Hand
But if you put c1=Ac, c2=Kc, c3=Qc, C4=Jc, C5=Td, now you are in state AcKcQcJcT, so the suit of the ten was lost. So if C6=Td then you get a valid state, the state AcKcQcJcTT that has hand value Straight Ace high.

You have to thinks in terms of the state you are at.

Please, I beg you, refrain from asking so many questions in a post. I'm helping you, but you are not helping me to get to the 100 posts required for level 2 :-)

Regards ...


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 11:16 pm 
Offline
PokerAI fellow
User avatar

Posts: 1239
Favourite Bot: my bot
Indiana wrote:
In fact, the spears port of the 2+2 code looks to me similar, if not the same as RayW code. But it has slower performance compared to SB, at least in Java. It's could be just the way the hand is encoded now.


Yes, there are quite a few improvements possible. The code I submitted originally was ripped out of some other stuff and I just did the bare minimum of work to get it working independently. I'll try to tune it for your tests over the next day or so.

In the meantime, Timmy ran the raw enumeration earlier this thread and reported this:

Timmy wrote:

Anyway,
--- Hands per second: 110,657,204, hands 133,784,560



Indiana wrote:
Within Ray's code there is also optimization along th way of the 7 cycles.


I don't understand


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 11:22 pm 
Offline
PokerAI fellow
User avatar

Posts: 1239
Favourite Bot: my bot
Adrian wrote:
Please, I beg you, refrain from asking so many questions in a post. I'm helping you, but you are not helping me to get to the 100 posts required for level 2 :-)


Just answer in seperate posts :lol: Are you looking forward to meeting Steve Brecher up there? :lol:

Thanks for your replies, will look at them some more tomorrow.


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 11:35 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Spears wrote:
In the meantime, Timmy ran the raw enumeration earlier this thread and reported this:

Timmy wrote:

Anyway,
--- Hands per second: 110,657,204, hands 133,784,560


Indiana wrote:
Within Ray's code there is also optimization along th way of the 7 cycles.


I don't understand



OK, what I meant is, that in the way I have tested your port I had much higher overhead than what you have posted, or what's in the RayW source code. The post from Timmy that your port (is this your Java port btw?, whos credits are that) runs with 100m/second I missed somehow. I thought ok, these are different test (they were, and they are the same now), whatever. Stupid me!

So, I reran [your port, I call it RayW now]:

Quote:
Evaluation tables loaded in 1.531 seconds
(7) RayW LUT hand evaluator, http://todo
--- Hands per second: 97297862, hands 133784560, checksum 0, total time: 1375


So it's the winner, 100m/sec pretty close to what Adrian reported (Adrian, happy now?). I will play a bit more with these things thou. At these speeds of 100m/sec a lot of things may impact the exact numbers.

P.S. RayW still have like 20M memory overhead, which I don't like much. I mean it's not like SB's ...

P.S.2. My next step when I log in back to this forum will be to update the code.zip with all these developments and OP.

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 11:39 pm 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
I now did a full retest along what you posted (i.e. all possible 7-card combinations). I tested it giving the hadn with the cards in increasing and decreasing order. All results are below.

The order of the cards does matter for the algorithms that make computations that need to sort the cards. The LUT does not need to sort the card, so it is not affected by the increasing or decreasing order (RayW is not performing further compression to compress states like Ac Kc 8c 7c 6c 2c, if it would perform further compression my theory is that the decreasing order would affect by reducing the time required).
indiana wrote:
Now, it looks eventually obvious the RayW code is going to be the winner, as it is just 7 lookups in a table

You don't need to do 7 lookups for each hand, because the lookups for states of 1, 2, 3, 4, 5 and 6 cards are done in the outer loops, so they are re-used.
indiana wrote:
Plus a shift right.

The shift is not needed, what the shift does is it gets the HandType from the HandValue to produce a list of the number of types of hands. You can put there the sum+=HandValue from your code.

indiana wrote:
In fact, the spears port of the 2+2 code looks to me similar, if not the same as RayW code.

I didn't looked at spars cod, but seems logical, spears said it uses Ray Wootons state table idea and most of his code
indiana wrote:
But it has slower performance compared to SB, at least in Java. It's could be just the way the hand is encoded now. Within Ray's code there is also optimization along th way of the 7 cycles.

The re-use of the 7 cards states does not affect so much the performance. From my computations, around 16% faster only.
In the 2+2 code the performance for the 7 cards evaluator in Java was similar to the performance of the C version, at least it had the same order of magnitude of hands / sec.
Didn't spears said something like 100 million hands? Where is the difference with your computation?

indiana wrote:
Steve Brecher is again smashing all competitors to the ground, way ahead of everyone else

Heh, I didn't needed to suscribe to this board to know this, we all knew this before starting, is the best 7 cards evaluator in the world, listed in the Guiness Book of Records :-)

Regards ...


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Mon Mar 31, 2008 11:47 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Adrian20XX wrote:
The shift is not needed, what the shift does is it gets the HandType from the HandValue to produce a list of the number of types of hands. You can put there the sum+=HandValue from your code.

I think we are reaching conclusion here and you managed to show me that RayW runs instantly and has constant complexity. In fact, in my whole algorithmic expeirence I have not seen something more constant than that :)

I removed now the junk around hand rank, and left onyl the Sum, and I reached the 140/sec:

Quote:
Evaluation tables loaded in 1.547 seconds
(7) Spears port of RayW LUT hand evaluator, http://todo
--- Hands per second: 142779680, hands 133784560, checksum 1528972275512, total time: 937

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Tue Apr 01, 2008 1:11 am 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
Adrian20XX wrote:
The shift is not needed, what the shift does is it gets the HandType from the HandValue to produce a list of the number of types of hands. You can put there the sum+=HandValue from your code.

I think we are reaching conclusion here and you managed to show me that RayW runs instantly and has constant complexity. In fact, in my whole algorithmic expeirence I have not seen something more constant than that :)
I removed now the junk around hand rank, and left onyl the Sum, and I reached the 140/sec:
Quote:
Evaluation tables loaded in 1.547 seconds
(7) Spears port of RayW LUT hand evaluator, http://todo
--- Hands per second: 142779680, hands 133784560, checksum 1528972275512, total time: 937

I'm not sure about what I'm going to say now, but I think it might be related. I'm not sure, but I think someone on the 2+2 thread said that the bits operations (in this case the shift) on some language were very expensive in terms of CPU consumed, I think it might have been in Java, or it might be a post by D&L that was programming in Visual Basic.
I've tried to find the post, but I didn't find it so far.

Also, now the evaluator on this thread is very close to the optimal LUT solution (as any LUT solution). There are a few minor improvements mentioned in the 2+2 thread, like using pointers instead of values in the array, or compacting the 6 cards states for hands like Ac Kc 8c 7c 6c 3c, but this will bring a very small performance gain. I've personally tested the pointers version and posted the results in the 2+2 thread, it is only faster like 2.28%
I have a few more small performance improvements I want to try, but as I said, the performance is now very close to the optimal.

Regards ...


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Tue Apr 01, 2008 6:31 am 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
I removed now the junk around hand rank, and left onyl the Sum, and I reached the 140/sec.
Evaluation tables loaded in 1.547 seconds
(7) Spears port of RayW LUT hand evaluator, http://todo
--- Hands per second: 142779680, hands 133784560, checksum 1528972275512, total time: 937

F it, F it, F it.
Good news for you, bad news for me. I've just discovered that I had on my code an easy optimization that Ray didn't had, in order to take some work out to the outer loops, so now instead of trailing by 10% I'm trailing by 20%, and you have an evaluator that should be around 10% faster, so you will probably evaluate around 157 million hands without the hand type calculation.

Just make this simple modification on the main loops:
Code:
//   int u0, u1, u2, u3, u4, u5;
   int *u0, *u1, *u2, *u3, *u4, *u5;

   count = 133784560;

   QueryPerformanceCounter(&timings);               // start High Precision clock

   for (c0 = 1; c0 < 53; c0++) {
      u0 = HR+HR[53+c0];
      for (c1 = c0+1; c1 < 53; c1++) {
         u1 = HR+u0[c1];
         for (c2 = c1+1; c2 < 53; c2++) {
            u2 = HR+u1[c2];
            for (c3 = c2+1; c3 < 53; c3++) {
               u3 = HR+u2[c3];
               for (c4 = c3+1; c4 < 53; c4++) {
                  u4 = HR+u3[c4];
                  for (c5 = c4+1; c5 < 53; c5++) {
                     u5 = HR+u4[c5];
                     for (c6 = c5+1; c6 < 53; c6++) {
                        handTypeSum[u5[c6] >> 12]++;
                     }
                  }
               }
            }
         }
      }
   }


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 399 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 20  Next


Who is online

Users browsing this forum: Google and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: