Image Image Image




Post new topic Reply to topic  [ 399 posts ]  Go to page Previous  1 ... 9, 10, 11, 12, 13, 14, 15 ... 20  Next
Author Message
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Jan 02, 2009 5:43 pm 
Offline
Junior member
User avatar

Posts: 29
Favourite Bot: none
My Java skills are rather weak but this is my attempt to make a smaller 5, 6, and 7 card evaluator than my LUT idea.

Code:
32bitword GetScore(64bitword hand)
{
  s = hand & 0x1fff;
  h = (hand >>> 16) & 0x1fff;
  d = (hand >>> 32) & 0x1fff;
  c = (hand >>> 48) & 0x1fff;

  value = Flush[s] | Flush[h] | Flush[d] | Flush[c];
  if (value > 0) return value;

  p1 = s;
  p2 = p1 & h; p1 = p1 | h;
  p3 = p2 & d; p2 = p2 | (p1 & d); p1 = p1 | d;
  p4 = p3 & c; p3 = p3 | (p2 & c); p2 = p2 | (p1 & c); p1 = p1 | c;

  value = Straight[p1];
  if (value > 0) return value;

  if (p4 > 0) {
    kicker = p1 ^ p4
    return quad_flag | Top1_16[p4] | Top1_12[kicker];
  }
   

  if (p3 > 0) {
    if (p2 > p3) {
      kicker = p2 ^ Bit1[p3];
      return house_flag | Top1_16[p3] | Top1_12[kicker];
    }
    kicker = p1 ^ Bit1[p3];
    return trip_flag | Top1_16[p3] | Top2_8[kicker];
  }

  if (p2 > 0) {
    if (Bit2[p2] > 0) {
      kicker = p1 ^ Bit2[p2];
      return twopair_flag | Top2_12[p2] | Top1_8[kicker];
    }
    kicker = p1 ^ Bit1[p2];
    return pair_flag | Top1_16[p2] | Top3_4[kicker];
  }

  return high_flag | Top5[p1];
}


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Jan 02, 2009 5:43 pm 
Offline
Junior member
User avatar

Posts: 29
Favourite Bot: none
Duplicate post edited


Last edited by mykey1961 on Fri Jan 02, 2009 5:47 pm, edited 1 time in total.

Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Jan 02, 2009 5:45 pm 
Offline
Junior member
User avatar

Posts: 29
Favourite Bot: none
Constants and inializations for the code above

Code:
high_flag = 0x100000;
pair_flag = 0x200000;
twopair_flag = 0x300000;
trip_flag = 0x400000;
straight_flag = 0x500000;
flush_flag = 0x600000;
house_flag = 0x700000;
quad_flag = 0x800000;
strflush_flag = 0x900000;


// Initialize tables


for (index = 0; index <= 0x1fc0; index++) {
  Flush[index] = 0;
  Straight[index] = 0;
  Top1_16[index] = 0;
  Top1_12[index] = 0;
  Top1_8[index] = 0;
  Top2_12[index] = 0;
  Top2_8[index] = 0;
  Top3_4[index] = 0;
  Top5[index] = 0;
  Bit1[index] = 0;
  Bit2[index] = 0;
}

for (c5 = 14; c5 > 4; c5--) {
  c4 = c5-1; c3 = c4-1; c2 = c3-1; c1 = c2-1;
  if (c1 == 1) c1 = 14;
  for (c6 = 14; c6 > 1; c6--) {
    if (c6 != c5+1) {
      for (c7 = c6-1; c7 > 1; c7--) {
        if (c7 != c5+1) {
          index = (1 <<< c1) | (1 <<< c2) | (1 <<< c3) | (1 <<< c4) | (1 <<< c5) | (1 <<< c6) | (1 <<< c7);
          Flush[index >>> 2] = strflush_flag | (c1 <<< 16) | (c2 <<< 12) | (c3 <<< 8) | (c4 <<< 4) | c5;
          Straight[index >>> 2] = straight_flag | (c1 <<< 16) | (c2 <<< 12) | (c3 <<< 8) | (c4 <<< 4) | c5;
        }
      }
    }
  }
}

for (c1 = 14; c1 > 5; c1--) {
  for (c2 = c1-1; c2 > 4; c2--) {
    for (c3 = c2-1; c3 > 3; c3--) {
      for (c4 = c3-1; c4 > 2; c4--) {
        for (c5 = c4-1; c5 > 1; c5--) {
          for (c6 = c5; c6 > 1; c6--) {
            for (c7 = c6; c7 > 1; c7--) {
              index = (1 <<< c1) | (1 <<< c2) | (1 <<< c3) | (1 <<< c4) | (1 <<< c5) | (1 <<< c6) | (1 <<< c7);
              if (Flush[index >>> 2] = 0) Flush[index >>> 2] = flush_flag | (c1 <<< 16) | (c2 <<< 12) | (c3 <<< 8) | (c4 <<< 4) | c5;
              Top5[index >>> 2] = high_flag | (c1 <<< 16) | (c2 <<< 12) | (c3 <<< 8) | (c4 <<< 4) | c5;
            }
          }
        }
      }
    }
  }
}

for (c1 = 14; c1 > 3; c1--) {
  for (c2 = c1-1; c2 > 2; c2--) {
    for (c3 = c2-1; c3 > 1; c3--) {
      for (c4 = c3; c4 > 1; c4--) {
        for (c5 = c4; c5 > 1; c5--) {
          for (c6 = c5; c6 > 1; c6--) {
           for (c7 = c6; c7 > 1; c7--) {
             index = (1 <<< c1) | (1 <<< c2) | (1 <<< c3) | (1 <<< c4) | (1 <<< c5) | (1 <<< c6) | (1 <<< c7);
             Top3_4[index >>> 2] = (c1 <<< 12) | (c2 <<< 8) | (c3 <<< 4);
           }
         }
       }
     }
   }
}

for (c1 = 14; c1 > 2; c1--) {
  for (c2 = c1-1; c2 > 1; c2--) {
    for (c3 = c2; c3 > 1; c3--) {
      for (c4 = c3; c4 > 1; c4--) {
        for (c5 = c4; c5 > 1; c5--) {
          for (c6 = c5; c6 > 1; c6--) {
           for (c7 = c6; c7 > 1; c7--) {
             index = (1 <<< c1) | (1 <<< c2) | (1 <<< c3) | (1 <<< c4) | (1 <<< c5) | (1 <<< c6) | (1 <<< c7);
             Top2_12[index >>> 2] = (c1 <<< 16) | (c2 <<< 12);
             Top2_8[index >>> 2] = (c1 <<< 12) | (c2 <<< 8);
             Bit2[index >>> 2] = (1 <<< (c1-2)) | (1 <<< (c2-2);
           }
         }
       }
     }
   }
}

for (c1 = 14; c1 > 1; c1--) {
  for (c2 = c1; c2 > 1; c2--) {
    for (c3 = c2; c3 > 1; c3--) {
      for (c4 = c3; c4 > 1; c4--) {
        for (c5 = c4; c5 > 1; c5--) {
          for (c6 = c5; c6 > 1; c6--) {
           for (c7 = c6; c7 > 1; c7--) {
             index = (1 <<< c1) | (1 <<< c2) | (1 <<< c3) | (1 <<< c4) | (1 <<< c5) | (1 <<< c6) | (1 <<< c7);
             Top1_16[index >>> 2] = (c1 <<< 16);
             Top1_12[index >>> 2] = (c1 <<< 12);
             Top1_8[index >>> 2] = (c1 <<< 8);
             Bit1[index >>> 2] = (1 <<< (c1-2));
           }
         }
       }
     }
   }
}


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Jan 02, 2009 9:25 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
What's that suppose to be?

Please instead of posting sources - just attach them as Java files. This is not 2+2, so you are able to attach files :)

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sat Jan 03, 2009 1:44 am 
Offline
Junior member
User avatar

Posts: 29
Favourite Bot: none
indiana wrote:
What's that suppose to be?

Please instead of posting sources - just attach them as Java files. This is not 2+2, so you are able to attach files :)



I'd post a java file, if I had created a java file, but what I have here is more like an idea expressed in as close to Java as I currently know how.

The hope is someone with java skills will take the code and make whatever tweaks it requires to make it working code.

This should execute on par, or better than code just being discussed before previously.


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Sat Jan 03, 2009 12:28 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
We have so many evaluators already - and so fast ones - that it's hard to obejctively judge a new one just by seeing new code - especially one that won't compile.

If you don't have a Java version, post the C/C++ one (and eventually include a benchmark function, similar to the one that is currenly used for the rest). I can then either run it on the same hardware that I used for the rest, or at least link it in the Todo's section of the OP.

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Thu Jan 15, 2009 12:49 pm 
Offline
New member
User avatar

Posts: 1
Favourite Bot: n/a
Played around with the hand evals a bit lately.

By doing a "manual" dump/load of the handRanks-Array for the spears2p2 evaluator, i cut the init-time by about 50% - at least on my pcs - compared to the standard Serialization that is used in the current code. Not sure if thats of any use for you guys.

Code:
   public static void saveHandRanks(String file) throws IOException{
      pokerai.game.eval.spears2p2.StateTableEvaluator.initialize();
      int[] handRanks = pokerai.game.eval.spears2p2.StateTableEvaluator.handRanks;       
      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
      bos.write(BitConverter.getBytes(handRanks.length));
      for(int i=0;i<handRanks.length;i++)
         bos.write(BitConverter.getBytes(handRanks[i]));
      bos.close();      
   }
      
   public static int[] loadHandRanks(String file) throws IOException{
      InputStream bis = new FileInputStream(file);
      byte[] b = new byte[65536];
      bis.read(b,0,4);
      int len = BitConverter.toInt(b, 0);
      int[] handRanks = new int[len];
      int rd=0, idx=0;
      while((rd=bis.read(b))==b.length)
         for(int j=0;j<rd;j+=4)
         {
            handRanks[idx]=BitConverter.toInt(b, j);
            idx++;
         }            
      
      return handRanks;
   }


Attachments:
alternativeSaving.zip [1.18 KB]
Downloaded 78 times
Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Jan 16, 2009 12:58 am 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Thanks! - I have updated OP with link to this post, so that we keep in mind to integrate it in the download (and other interested can easily find it too).

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Jan 16, 2009 11:56 am 
Offline
Regular member
User avatar

Posts: 64
Favourite Bot: MCTSBot
I found it more useful to wrap the ObjectOutputStream in a ZipOutputStream to reduce the filesize to 25 megs. Save and load time doubles though.


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Thu Feb 26, 2009 12:52 am 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
Just a small comment as I've being making some cosmetic adjustments to my stuff and then came back to re-read what's up.

I see people come to this thread or new thread from time to time with new evaluators, and I think they are missing the point. The enumeration problem is much more important in terms of performance.
Look at it this way. On the first post of this thread, RayW is at 142,779,680 vs. SteveB at 34,659,212. That's a 4,119530473 speed up (four times faster).
I have the LUT running at 375 million hands per second. Only a 2,626424152 speed up (two and a half time faster) over the code you have (I'm pretty sure the difference is mainly due to Spears port or to Java).
But, I have my pre-flop evals running at this numbers:
Code:
Players:                                      2           3           4           5           6
Cards In Deck:                               48          46          44          42          40
Evals:                                  3424608     4112262     4344032     4253340     3948048
Milliseconds:                           0,86621     1,03759     1,00951      1,5208      2,0702
Seconds:                             0,00086621  0,00103759  0,00100951   0,0015208   0,0020702
Equivalent Million Evals / Second:  3953,553988 3963,282221 4303,109429 2796,778012 1907,085306
7 cards eval Million Evals / Second:        375         375         375         375         375
Speed Up:                           10,54281063 10,56875259 11,47495848 7,458074698 5,085560815

So, the speed up for the enumeration can be much bigger than the one from the better evaluation functions. Plus, I expect a similar speed up from the explotation of hole cards isomorphisms.

On a side note, I would like to see mykey1961's new idea.
Altough I think very few people now can raise the bar for the evaluators (many of them brilliant and many of them that have put tons and tons of time thinking about it, and I can see in this list Andrew Prock, University of Alberta, and Andrzej Nironen for Monte Carlo that might have already TODAY something that could be a break thru), I don't expect too many people to devote the time that it takes to raise it up even more, altough we can find the ocasional Gothor's of this world.

OK, enough of evaluators for me for these days, have to get back to play poker :-)


Top
 Profile  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Thu Feb 26, 2009 8:22 pm 
Offline
Junior member
User avatar

Posts: 39
Location: FRANCE (ELSASS)
Favourite Bot: ElsassTracker
Adrian20XX wrote:

I don't expect too many people to devote the time that it takes to raise it up even more, altough we can find the ocasional Gothor's of this world.

OK, enough of evaluators for me for these days, have to get back to play poker :-)


i think you are the only one who knows how my still unfinished evaluator works...


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Thu Feb 26, 2009 9:58 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Adrian20XX wrote:
Just a small comment as I've being making some cosmetic adjustments to my stuff and then came back to re-read what's up.

I see people come to this thread or new thread from time to time with new evaluators, and I think they are missing the point. The enumeration problem is much more important in terms of performance.
Look at it this way. On the first post of this thread, RayW is at 142,779,680 vs. SteveB at 34,659,212. That's a 4,119530473 speed up (four times faster).
I have the LUT running at 375 million hands per second. Only a 2,626424152 speed up (two and a half time faster) over the code you have (I'm pretty sure the difference is mainly due to Spears port or to Java).
But, I have my pre-flop evals running at this numbers:
Code:
Players:                                      2           3           4           5           6
Cards In Deck:                               48          46          44          42          40
Evals:                                  3424608     4112262     4344032     4253340     3948048
Milliseconds:                           0,86621     1,03759     1,00951      1,5208      2,0702
Seconds:                             0,00086621  0,00103759  0,00100951   0,0015208   0,0020702
Equivalent Million Evals / Second:  3953,553988 3963,282221 4303,109429 2796,778012 1907,085306
7 cards eval Million Evals / Second:        375         375         375         375         375
Speed Up:                           10,54281063 10,56875259 11,47495848 7,458074698 5,085560815

So, the speed up for the enumeration can be much bigger than the one from the better evaluation functions. Plus, I expect a similar speed up from the explotation of hole cards isomorphisms.

On a side note, I would like to see mykey1961's new idea.
Altough I think very few people now can raise the bar for the evaluators (many of them brilliant and many of them that have put tons and tons of time thinking about it, and I can see in this list Andrew Prock, University of Alberta, and Andrzej Nironen for Monte Carlo that might have already TODAY something that could be a break thru), I don't expect too many people to devote the time that it takes to raise it up even more, altough we can find the ocasional Gothor's of this world.

OK, enough of evaluators for me for these days, have to get back to play poker :-)


That's a good point I only don't think the speed has anythin to do with Java, at least in the last C and Java were pulling the same (very similar performance, nothing in the range of x2, x3 ...).

_________________
indiana


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

Posts: 7731
Favourite Bot: V12
That's not directly relevant for this thread, but Steve Brecher just won a WTP even (over 1m$ in winnings), where he also set the record for the longest WTP event final table:

http://www.fulltiltpoker.com/steveBrecher.php

With that I guess we won't see much updates in his hand evaluator, but congratulations anyway.

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: 2+2 Hand Evaluator in Java
PostPosted: Wed Apr 01, 2009 10:31 am 
Offline
PokerAI fellow
User avatar

Posts: 1613
Location: Austria
Favourite Bot: Marvin
Here's a direct port (prototype) of the lookup-based hand evaluator (just the lookup part) from the 2+2 forums to Java/Meerkat.

It uses the original HandRanks.dat file and thus has to convert the cards to the appropriate format (int index values).

If you use it, you have to increase the Java heap size (usually using -Xms512M -Xmx512M or something like that). It's a singleton, but still reads the 128M file into memory once...

If you need to generate the HandRanks.dat file, you can use Visual C++ Express 2008 and use the code published on Coding the Wheel:

http://www.codingthewheel.com/archives/ ... or-roundup

I may port the generator at some point as well to get rid of the multiplications and additions in the lookup functions. At least, now we're not depending on the JNI call overhead anymore.

Here's the code:

Code:
package supersonic.pokerbot.common;

import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.io.IOException;

import com.biotools.meerkat.Card;
import com.biotools.meerkat.Hand;
import com.biotools.meerkat.HandEval;

public class LookupHandEvaluator implements HandEval {

   private int HR[];
   private static boolean usable = false;

   private static LookupHandEvaluator instance = null;


   public static LookupHandEvaluator getInstance( String fileName  ) {
      if( instance == null ) {
         instance = new LookupHandEvaluator( fileName );
      }
      if( ! usable ) {
         System.err.println( "Lookup Hand Evaluator not usable." );
         instance = null;
      }
      return( instance );
   }


   private LookupHandEvaluator( String fileName ) {
      HR = new int[ 32487834 ];
      byte[] buffer = new byte[ 59996 ];
      int countRead;
      int index = 0;
      int bufferIndex = 0;

      try {
         FileInputStream stream = new FileInputStream( fileName );
         while( stream.available() > 0 ) {
            countRead = stream.read( buffer, 0, 59996 );
            for( bufferIndex = 0; bufferIndex < countRead; bufferIndex += 4, index++ ) {
               HR[ index ] = ( buffer[ bufferIndex ] >= 0 ? buffer[ bufferIndex ] : buffer[ bufferIndex ] + 256 )
                   + ( buffer[ bufferIndex + 1 ] >= 0 ? buffer[ bufferIndex + 1 ] : buffer[ bufferIndex + 1 ] + 256 ) * 256
                  + ( ( buffer[ bufferIndex + 2 ] >= 0 ? buffer[ bufferIndex + 2 ] : buffer[ bufferIndex + 2 ] + 256 )
                        + ( buffer[ bufferIndex + 3 ] >= 0 ? buffer[ bufferIndex + 3 ] : buffer[ bufferIndex + 3 ] + 256 ) * 256 ) * 65536;
            }
         }
      } catch( FileNotFoundException fnfe ) {
         System.err.println( fnfe.getMessage() );
         usable = false;
      } catch( IOException ioe ) {
         System.err.println( ioe.getMessage() );
         usable = false;
      }
      usable = true;
      if( this.rankHand( new Hand( "2c 2s 2h 3d 4s" ) ) >> 12 != 4 ) {
         usable = false;
      }
   }


   public boolean isUsable() {
      return( usable );
   }


   public int rankHand( Hand h ) {
      if( ! usable ) {
         return -1;
      }

      int size = h.size();
      if( size < 5 ) {
         return -1;
      }

      int p = 53;
      for( int pos = 1; pos <= size; pos++ ) {
//         System.out.println( h.getCard( pos ) + ": " + ( h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) );
//         System.out.print( "HR ( " + ( p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) + " ) = " );
         p = HR[ p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ];
//         System.out.println( p );
      }

      return ( size < 7 ? HR[ p ] : p );
   }


   public int rankHand5( Hand h ) {
      if( ! usable ) {
         return -1;
      }

      int p = 53;
      for( int pos = 1; pos <= 5; pos++ ) {
//         System.out.println( h.getCard( pos ) + ": " + ( h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) );
//         System.out.print( "HR ( " + ( p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) + " ) = " );
         p = HR[ p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ];
//         System.out.println( p );
      }

      return ( HR[ p ] );
   }


   public int rankHand6( Hand h ) {
      if( ! usable ) {
         return -1;
      }

      int p = 53;
      for( int pos = 1; pos <= 6; pos++ ) {
//         System.out.println( h.getCard( pos ) + ": " + ( h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) );
//         System.out.print( "HR ( " + ( p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) + " ) = " );
         p = HR[ p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ];
//         System.out.println( p );
      }

      return ( HR[ p ] );
   }


   public int rankHand7( Hand h ) {
      if( ! usable ) {
         return -1;
      }

      int p = 53;
      for( int pos = 1; pos <= 7; pos++ ) {
//         System.out.println( h.getCard( pos ) + ": " + ( h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) );
//         System.out.print( "HR ( " + ( p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ) + " ) = " );
         p = HR[ p + h.getCard( pos ).getRank() * 4 + h.getCard( pos ).getSuit() + 1 ];
//         System.out.println( p );
      }

      return ( p );
   }


   public int rankHand( Card c1, Card c2, Hand h ) {
      h.addCard( c1 );
      h.addCard( c2 );

      int rank = rankHand( h );

      h.removeCard();
      h.removeCard();

      return rank;
   }
}




Usage:

Code:

package supersonic.pokerbot.common;

import com.biotools.meerkat.Card;
import com.biotools.meerkat.Hand;
import com.biotools.meerkat.HandEval;


public class Test {

   public static void main( String[] args ) {
      HandEval handEval = LookupHandEvaluator.getInstance( "HandRanks.dat" );

      Card card0 = new Card( "Th" );
      Card card1 = new Card( "4d" );
      Hand board = new Hand( "Td Qh Kh Jh" );

      Hand hand = new Hand( board );
      hand.addCard( card0 );
      hand.addCard( card1 );

      System.out.println( "Eval: " + handEval.rankHand( hand ) );
      System.out.println( "Rank: " + ( handEval.rankHand( hand ) >> 12 ) );
      System.out.println( "Salt: " + ( handEval.rankHand( hand ) & 0xFFF ) );
   }
}



Top
 Profile E-mail  
 
 Post subject: Re: 2+2 Hand Evaluator in Java
PostPosted: Wed Apr 01, 2009 10:53 am 
Offline
Regular member
User avatar

Posts: 64
Location: Edinburgh, Scotland flounderhead@gmail.com
Favourite Bot: Kryten
Just curious (don't speak Java):
HR[ index ] = ( buffer[ bufferIndex ] >= 0 ? buffer[ bufferIndex ] : buffer[ bufferIndex ] + 256 )

- are bytes signed in java or do I just not understand above line?

For reading in the LUT:
- would RandomAccessFile::readInt() be faster?
- would using sun.misc.Unsafe be much faster?

- how does the lookup performance compare for *random* (non-sequential) lookups, did you measure that?

I once ported the code to c# and found random access lookups to be much slower than in native code.

Thanks!


Top
 Profile E-mail  
 
 Post subject: Re: 2+2 Hand Evaluator in Java
PostPosted: Wed Apr 01, 2009 11:48 am 
Offline
PokerAI fellow
User avatar

Posts: 1613
Location: Austria
Favourite Bot: Marvin
Hi there,

Thanks for the suggestions.

Yes, bytes are signed in Java. as are ints.

FileReader::readInt() got me into all kinds of problems, mainly performance (but also signed/unsigned problems). Reading a buffer in the 60k area at once brought immense performance advantages.

Actually, reading the file (which is done only once at startup) is < 5 seconds, so nothing to really worry about. Using readInt() 32 million times was in the area of 1 minute...

I didn't measure/benchmark lookup performance yet. I might do that against the Java based HandEvlauator by the UoC people. And later against a HandRanks.dat file specifically optimized for Meerkat card index values (thus saving the conversions).

I also think about enhancing the table - once I generate it in Java - to 2/3/4 card lookups as well, right now it has 0 values in the table fot those. It would be faster for example to check whether the board is paired on the flop...

Cheers, Supersonic.


Top
 Profile E-mail  
 
 Post subject: Re: 2+2 Hand Evaluator in Java
PostPosted: Wed Apr 01, 2009 8:43 pm 
Offline
PokerAI fellow
User avatar

Posts: 7731
Favourite Bot: V12
Is the generator different than the Java port of the 2+2 evaluator?

(btw, I will joint this thread with this one once the discussion is over).

_________________
indiana


Top
 Profile E-mail  
 
 Post subject: Re: 2+2 Hand Evaluator in Java
PostPosted: Wed Apr 08, 2009 10:50 am 
Offline
PokerAI fellow
User avatar

Posts: 1613
Location: Austria
Favourite Bot: Marvin
Actually, the one I'm going to implement will be just a tick different.

I like the idea to have the table file generated if not existant already. I'll do that as well in the final version.

What I don't like in the 2+2 direct port is the p = HV[ 53 + Card.getIndex() ] and later p = HV[ p + Card.getIndex() + 1 ] idea. Meerkat using 0..51 for card index vs. 2+2 using 1..52 gets a bit in the way here.

While I understand that leaving the 0-index space for 5-card and 6-card hand lookups is an advantage, I plan to be able to lookup via p = HV[ Card.getIndex() ] for the first card and p = HV[ p + Card.getIndex() ] for the folliowing cards. That saves one instruction per card. Not much, but if you call it billions of times it adds up.

How can I then lookup 5- or 6-card hands? By having a separate table for those.

getRank5( Hand h ), getRank6( Hand h ), and getRank7(Hand h ) will use the respective table directly, while getRank( Hand h ) gets the size of the hand first and uses the appropriate table afterwards. Usually you know how many cards your hand has when getting the rank, so you'd call the specific functions anyway.

All three tables added will still be smaller than the 2+2 table (by a mere 53 bytes at least, if I'm not mistaken on a very brief thinking about it).

I also think about adding getRank4 .. getRank1 options, but I'm not sure about that yet.

Too bad we have no inlining in Java, as that would save the time to put parameters on the stack etc...

I hope to get this implemented by the end of April.

Cheers, Supersonic.


Top
 Profile E-mail  
 
 Post subject: Re: 2+2 Hand Evaluator in Java
PostPosted: Wed Apr 08, 2009 11:39 am 
Offline
PokerAI fellow
User avatar

Posts: 1239
Favourite Bot: my bot
supersonic wrote:
Too bad we have no inlining in Java, as that would save the time to put parameters on the stack etc...


Doesn't the JIT compiler do this? If this is no good, can't you use refactoring to do it?

Array lookups in Java used to be bounds checked: if they still are in modern JIT compilers I guess that will have a performance impact. You can't remove the bounds checking from the bytecode - I checked.

It would be nice to have a version of this evaluator that works for 6 cards: I don't think my port does for reasons I don't understand.


Top
 Profile E-mail  
 
 Post subject: Re: 7-card Hand Evaluators
PostPosted: Fri Apr 10, 2009 7:59 am 
Offline
Senior member
User avatar

Posts: 223
Favourite Bot: N/A
indiana wrote:
(1) Spears adaptation of RayW LUT hand evaluator[/b], http://pokerai.org/pf3, http://forumserver.twoplustwo.com
--- Hands per second: 142779680, hands 133784560, checksum 1528972275512, total time: 937
(4) Spears port of 2+2 evaluator, http://pokerai.org/pf3
--- Hands per second: 23783922, hands 133784560, checksum 450334402748, total time: 5625

What means "Spears port of 2+2 evaluator?" I mean what code if it's not RayW's?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 399 posts ]  Go to page Previous  1 ... 9, 10, 11, 12, 13, 14, 15 ... 20  Next


Who is online

Users browsing this forum: Google and 7 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: