Does Paul's version come up with a number for a hand that would inform
a decision? LS
Yes.
I deleted some unused variables and did very little reformatting.
This is pretty close to what he posted:
/* BEGIN pokeref.h */
#ifndef H_POKEREF_H
#define H_POKEREF_H
#define CLUB_SUIT (1)
#define DIAMOND_SUIT (2)
#define HEART_SUIT (4)
#define SPADE_SUIT (8)
#define RANK_SHL (27)
#define SUBR_SHL (13)
#define STRAIGHT_FLUSH_SCORE (8 << RANK_SHL)
#define FOUR_KIND_SCORE (7 << RANK_SHL)
#define FULL_HOUSE_SCORE (6 << RANK_SHL)
#define FLUSH_SCORE (5 << RANK_SHL)
#define STRAIGHT_SCORE (4 << RANK_SHL)
#define THREE_KIND_SCORE (3 << RANK_SHL)
#define TWO_PAIR_SCORE (2 << RANK_SHL)
#define TWO_KIND_SCORE (1 << RANK_SHL)
#define ONE_PAIR_SCORE (TWO_KIND_SCORE)
#ifndef DWORD
typedef unsigned long DWORD;
#endif
#ifndef BYTE
typedef unsigned long BYTE;
#endif
#ifndef WORD
typedef unsigned long WORD;
#endif
typedef struct {
int len;
BYTE entry[52];
} CardPileType;
#endif
/* END pokeref.h */
/* BEGIN pokeref.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "pokeref.h"
DWORD CardValue[52] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
};
DWORD CardMask[52] = {
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
0x1000,
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
0x1000,
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
0x1000,
1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
0x1000
};
DWORD CardSuit[52] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
};
DWORD PokerScore( BYTE * h )
{
DWORD u,y,z;
DWORD c0,c1,c2,c3,c4;
DWORD m1,m2,m3,m4;
/*
// Make suits powers of two.
*/
u = CardSuit[h[0]];
u |= CardSuit[h[1]];
u |= CardSuit[h[2]];
u |= CardSuit[h[3]];
u |= CardSuit[h[4]];
/*
// Test for single suitedness
*/
u = u&(u-1);
/*
// Make cards powers of two.
*/
c0 = CardMask[h[0]];
c1 = CardMask[h[1]];
c2 = CardMask[h[2]];
c3 = CardMask[h[3]];
c4 = CardMask[h[4]];
/*
// Build masks of 1, 2, 3, and 4 of a kind.
*/
m1 = c0 | c1;
m2 = c1 & c0;
m2 |= c2 & m1;
m1 |= c2;
m2 |= c3 & m1;
m1 |= c3;
m2 |= c4 & m1;
m1 |= c4;
if( m2==0 ) { /*// No pairs?*/
/*
// Is the mask a sequence of 1 bits?
*/
z = m1&(m1-1);
z ^= m1;
y = (z<<5) - z;
/*
// Deal with the bicycle/wheel 5,4,3,2,Ace straight
*/
if ( m1 == 0x100F ) {
if( u!=0 ) return STRAIGHT_SCORE + 0xF;
return STRAIGHT_FLUSH_SCORE + 0xF;
}
if( y==m1 ) {
if( u!=0 ) return STRAIGHT_SCORE + m1;
return STRAIGHT_FLUSH_SCORE + m1;
}
if( u!=0 ) return m1; // Nothing
return FLUSH_SCORE + m1;
}
/*
// m1 = c0 | ... | c4
// m2 = (c0 & c1) | ((c0|c1) & c2)
| ((c0|c1|c2) & c3) | ((c0|c1|c2|c3) & c4)
// m3 = mask of 3 of a kind.
// m4 = mask of 4 of a kind.
*/
m1 = c0 | c1;
m2 = c1 & c0;
m3 = c2 & m2;
m2 |= c2 & m1;
m1 |= c2;
m4 = c3 & m3;
m3 |= c3 & m2;
m2 |= c3 & m1;
m1 |= c3;
m4 |= c4 & m3;
m3 |= c4 & m2;
m2 |= c4 & m1;
m1 |= c4;
m1 &= ~m2;
if(m3 == 0) {
if( (m2&(m2 - 1))==0 )
return TWO_KIND_SCORE + (m2 << SUBR_SHL) + m1;
return TWO_PAIR_SCORE + (m2 << SUBR_SHL) + m1;
}
m2 &= ~m3;
if( m4==0 ) {
if( m2==0 )
return THREE_KIND_SCORE + (m3 << SUBR_SHL) + m1;
return FULL_HOUSE_SCORE + (m3 << SUBR_SHL) + m2;
}
return FOUR_KIND_SCORE + (m4 << SUBR_SHL) + m1;
}
//char suitdisp[9] = { 0, 5, 4, 0, 3, 0, 0, 0, 6 };
char suitdisp[9] = { 0, 'c', 'd', 0, 'h', 0, 0, 0, 's' };
void DisplayCard( BYTE c ) {
char s[4];
s[0] = " 1 "[CardValue[c]];
s[1] = "234567890JQKA"[CardValue[c]];
s[2] = suitdisp[CardSuit[c]];
s[3] = '\0';
printf(" %s ",s);
}
void DisplayHand( CardPileType * h ) {
int v=0;
int i;
for(i=0;i<5;i++) DisplayCard( h->entry
);
printf(" => %08X\n",PokerScore(&h->entry[0]));
}
CardPileType Deck, Hand;
void Shuffle( CardPileType * c ) {
int i = c->len,j;
for(;i>1 {
BYTE t;
j = rand() % i;
i--;
t = c->entry;
c->entry = c->entry[j];
c->entry[j] = t;
}
}
int Deal( CardPileType * h, CardPileType * d, int n )
{
int i;
for( i=0; i<n && d->len>0; i++ ) {
d->len--;
h->entry[ h->len ] = d->entry[ d->len ];
h->len++;
}
return i;
}
void InitCards()
{
int i;
Deck.len = 52;
for(i=0;i<52;i++)
Deck.entry = i;
Shuffle(&Deck);
Hand.len = 0;
}
#define ARCHIVE_SHL 6
#define ARCHIVE_NUM (1<<(ARCHIVE_SHL))
CardPileType HandArchive[ARCHIVE_NUM];
int main(void)
{
int i,j;
int c;
srand( (unsigned int)time((void *)0) );
InitCards();
printf("STRAIGHT_FLUSH_SCORE %08x\n",STRAIGHT_FLUSH_SCORE );
printf("FOUR_KIND_SCORE %08x\n",FOUR_KIND_SCORE );
printf("FULL_HOUSE_SCORE %08x\n",FULL_HOUSE_SCORE );
printf("FLUSH_SCORE %08x\n",FLUSH_SCORE );
printf("STRAIGHT_SCORE %08x\n",STRAIGHT_SCORE );
printf("THREE_KIND_SCORE %08x\n",THREE_KIND_SCORE );
printf("TWO_PAIR_SCORE %08x\n",TWO_PAIR_SCORE );
printf("TWO_KIND_SCORE %08x\n",TWO_KIND_SCORE );
for(i=0;i<ARCHIVE_NUM;i++) {
Deal(&Hand,&Deck,5);
if( i<32 ) DisplayHand(&Hand);
HandArchive = Hand;
Deal(&Deck,&Hand,5); // Add hand back into Deck.
Shuffle(&Deck); // Reshuffle Deck.
}
for(c=0;c<1024;c++) {
for(j=0,i=0;i<ARCHIVE_NUM;i++) {
j += PokerScore(&HandArchive.entry[0]);
}
}
printf("\nRigged hands\n\n");
Hand.len = 5;
Hand.entry[0] = 12;
Hand.entry[1] = 12+13;
Hand.entry[2] = 12+26;
Hand.entry[3] = 12+39;
Hand.entry[4] = 11;
DisplayHand(&Hand);
Hand.entry[0] = 12;
Hand.entry[1] = 12+13;
Hand.entry[2] = 12+26;
Hand.entry[3] = 11+39;
Hand.entry[4] = 11;
DisplayHand(&Hand);
Hand.entry[0] = 12;
Hand.entry[1] = 11+13;
Hand.entry[2] = 10+26;
Hand.entry[3] = 9+39;
Hand.entry[4] = 8;
DisplayHand(&Hand);
Hand.entry[0] = 12;
Hand.entry[1] = 12+13;
Hand.entry[2] = 2+26;
Hand.entry[3] = 3+39;
Hand.entry[4] = 4;
DisplayHand(&Hand);
Hand.entry[0] = 2;
Hand.entry[1] = 2+13;
Hand.entry[2] = 3+26;
Hand.entry[3] = 3+39;
Hand.entry[4] = 4;
DisplayHand(&Hand);
Hand.entry[0] = 0;
Hand.entry[1] = 0+13;
Hand.entry[2] = 1+26;
Hand.entry[3] = 2+39;
Hand.entry[4] = 3;
DisplayHand(&Hand);
Hand.entry[0] = 0;
Hand.entry[1] = 0+13;
Hand.entry[2] = 1+26;
Hand.entry[3] = 1+39;
Hand.entry[4] = 2;
DisplayHand(&Hand);
Hand.entry[0] = 3;
Hand.entry[1] = 2+13;
Hand.entry[2] = 1+26;
Hand.entry[3] = 0+39;
Hand.entry[4] = 12;
DisplayHand(&Hand);
Hand.entry[0] = 4;
Hand.entry[1] = 3+13;
Hand.entry[2] = 2+26;
Hand.entry[3] = 1+39;
Hand.entry[4] = 0;
DisplayHand(&Hand);
Hand.entry[0] = 12;
Hand.entry[1] = 12+13;
Hand.entry[2] = 11+26;
Hand.entry[3] = 11+39;
Hand.entry[4] = 10;
DisplayHand(&Hand);
Hand.entry[0] = 12+ 26;
Hand.entry[1] = 12+13;
Hand.entry[2] = 11+26;
Hand.entry[3] = 11;
Hand.entry[4] = 10+39;
DisplayHand(&Hand);
Hand.entry[0] = 12;
Hand.entry[1] = 0;
Hand.entry[2] = 1;
Hand.entry[3] = 2;
Hand.entry[4] = 3;
DisplayHand(&Hand);
Hand.entry[0] = 11 + 26;
Hand.entry[1] = 0;
Hand.entry[2] = 1;
Hand.entry[3] = 2;
Hand.entry[4] = 3;
DisplayHand(&Hand);
Hand.entry[0] = 11 + 26;
Hand.entry[1] = 4;
Hand.entry[2] = 1;
Hand.entry[3] = 2;
Hand.entry[4] = 3;
DisplayHand(&Hand);
return 0;
}
/* END pokeref.c */