Note: I forgot to mention in my previous post that using bit vectors is probably not the best way to implement this HE in CL -- we'll see.
First update... There are four C files. One is a header file that contains quite a few defs. I'm going to hold off on this one until later since copying it directly to the CL implementation is probably not going to work that well. One of the files contains mostly precomputed arrays for dealing with the various flush hands (ie a lookup table). This was done this way
to create an extremely fast HE -- I don't think that I'll need to precompute all of these values, but we'll see later on. The other file that I'm going to ignore for the time being tests all possible 52 C 5 hands.
Below are the function definitions for the lib file.
http://www.suffecool.net/poker/code/pokerlib.c
Code:
// perform a binary search on a pre-sorted array
int findit( int key )
One of the things that I did happen to read about the implementation is that Kevin originally used a BST to find some kind of values for the hands. Someone else contributed a hash table implementation that was 2.7x faster. As CL as both of these data structures in the language, I'm going to save this for later.
Code:
// This routine initializes the deck. A deck of cards is
// simply an integer array of length 52 (no jokers). This
// array is populated with each card, using the following
// scheme:
//
// An integer is made up of four bytes. The high-order
// bytes are used to hold the rank bit pattern, whereas
// the low-order bytes hold the suit/rank/prime value
// of the card.
//
// +--------+--------+--------+--------+
// |xxxbbbbb|bbbbbbbb|cdhsrrrr|xxpppppp|
// +--------+--------+--------+--------+
//
// p = prime number of rank (deuce=2,trey=3,four=5,five=7,...,ace=41)
// r = rank of card (deuce=0,trey=1,four=2,five=3,...,ace=12)
// cdhs = suit of card
// b = bit turned on depending on rank of card
init_deck( int *deck )
{
int i, j, n = 0, suit = 0x8000;
for ( i = 0; i < 4; i++, suit >>= 1 )
for ( j = 0; j < 13; j++, n++ )
deck[n] = primes[j] | (j << 8) | suit | (1 << (16+j));
}
Looks like fun... I'll probably implement this portion of the code tonight (init-deck).
Code:
// This routine will search a deck for a specific card
// (specified by rank/suit), and return the INDEX giving
// the position of the found card. If it is not found,
// then it returns -1
int find_card( int rank, int suit, int *deck )
// This routine takes a deck and randomly mixes up
// the order of the cards.
shuffle_deck( int *deck )
print_hand( int *hand, int n )
Without really looking at the code, I'm pretty sure that I'll get all of these things for free (or nearly free) in CL, so I'm going to save them for now.
Code:
int hand_rank( short val )
{
if (val > 6185) return(HIGH_CARD); // 1277 high card
if (val > 3325) return(ONE_PAIR); // 2860 one pair
if (val > 2467) return(TWO_PAIR); // 858 two pair
if (val > 1609) return(THREE_OF_A_KIND); // 858 three-kind
if (val > 1599) return(STRAIGHT); // 10 straights
if (val > 322) return(FLUSH); // 1277 flushes
if (val > 166) return(FULL_HOUSE); // 156 full house
if (val > 10) return(FOUR_OF_A_KIND); // 156 four-kind
return(STRAIGHT_FLUSH); // 10 straight-flushes
}
short eval_5cards( int c1, int c2, int c3, int c4, int c5 )
short eval_5hand( int *hand )
// This is a non-optimized method of determining the
// best five-card hand possible out of seven cards.
// I am working on a faster algorithm.
short eval_7hand( int *hand )
These I'll definitely have to write up. It's getting a bit late, so I'll probably save them for tomorrow though.