Two Plus Two Newer Archives  

Go Back   Two Plus Two Newer Archives > Internet Gambling > Software
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools Display Modes
  #11  
Old 07-18-2006, 11:43 AM
fnord_too fnord_too is offline
Senior Member
 
Join Date: May 2004
Location: February made me shiver
Posts: 9,200
Default Re: Algorithm for Figuring out Your Hold\'em Hand

I have written code that can compare up to nine card hands, after that I really did not want to worry about double flushes, straights, etc. But I did not know about the sourceforge project when I wrote mine (also, since I did it like 7 years ago originally, it may not have existed then, though I have since re-written it in java).
Reply With Quote
  #12  
Old 07-25-2006, 03:53 PM
Shroomy Shroomy is offline
Senior Member
 
Join Date: Apr 2006
Location: Miami FLA
Posts: 465
Default Re: Algorithm for Figuring out Your Hold\'em Hand

See my post in the probability section about poker calculator.
Reply With Quote
  #13  
Old 07-25-2006, 04:07 PM
disjunction disjunction is offline
Senior Member
 
Join Date: Nov 2004
Posts: 3,352
Default Re: Algorithm for Figuring out Your Hold\'em Hand

[ QUOTE ]
I might be interested in some sort of code to work out how strong a hand is with less than 7 cards. So say after turn, it could classify the hands as 'two pair' or 'two pair with flush draw' or 'flush draw' etc.

[/ QUOTE ]

I've written this type of code. It's more tedious and more open for interpretation than you'd think. The problem is how to label the various straight draws and gutshots mixed in with overcards.
Reply With Quote
  #14  
Old 07-25-2006, 04:12 PM
disjunction disjunction is offline
Senior Member
 
Join Date: Nov 2004
Posts: 3,352
Default Re: Algorithm for Figuring out Your Hold\'em Hand

If you're going to do this for a living, the most important lesson you can learn is that no one will EVER through your code. This is important for email communications. Reading someone else's code is actually harder in some sense than writing your own.

I am not trying to be cute -- I made this mistake as an intern.

Also, an important skill is to able to write adequate tests for your code and debug it. Bad engineers skip this part too often. Poker code is good practice for this.



[ QUOTE ]
In case anyone was wondering... here is the code I came up with. I still have to find a way to check for A2345 straights and straightflushes, since I made the Ace count as high when I coded it.

<font class="small">Code:</font><hr /><pre> HAND evalHand(Player * thePlayer, Board * theBoard)
{
//stores the player's hole cards
vector&lt;Card&gt; holeCards;
holeCards.push_back(thePlayer-&gt;getHoleCard(0));
holeCards.push_back(thePlayer-&gt;getHoleCard(1));

//stores the board cards
vector&lt;Card&gt; boardCards;
for(int i = 0; i &lt; 5; ++i){
boardCards.push_back(theBoard-&gt;at(i));
}
sort(boardCards.begin(), boardCards.end());

//add holecards to form a "total" hand, they are left seperate for "incomplete" hand evaluation
//later on in a different function
vector&lt;Card&gt; allCards;
allCards.push_back(holeCards[0]);
allCards.push_back(holeCards[1]);

for(int i = 0; i &lt; 5; ++i){
allCards.push_back(boardCards[i]);
}

sort(allCards.begin(), allCards.end(), sortBySuit()); //first sort by suit to check for straightflush

//------begin checking hands--------------------


//************check for flush or straightflush*********************
bool flush = false;
Card c = allCards[6];
int flushCount = 1, straightFlushCount = 1;
int flushIndex= 6, straightFlushIndex = 6;

for(int i = 5; i &gt;= 0; --i){
//loop through the array backwards, checking the highest card first
if(c.getSuit() == allCards[i].getSuit()){ //next in flush
if(c.getRank() - allCards[i].getRank() == 1){ //straight-flush count
straightFlushCount++; //begin building straightflush
flushCount++;
} else { //no straight-flush, but still could be flush
straightFlushCount = 1;
straightFlushIndex = i;
flushCount++;
}
} else { //no flush or straightflush
straightFlushCount = 1;
straightFlushIndex = i;
if(!flush){ //don't reset flush counts if we already have one
flushCount = 1;
flushIndex = i;
}

}
if(flushCount &gt;= 5){ //flush!
if(straightFlushCount == 5) { //could be a straight-flush
return STRAIGHTFLUSH;
} else {
flush = true; //can't return yet since we have to check for rest of straightflush,
//quads or fullhouse
}
}
c = allCards[i];
}


//*********check for four of a kind, trips, two pair, one pair******************
int threeKind = 0, pair = 0;
int pairCount[7] = {1,1,1,1,1,1,1};
for(int j = 0; j &lt; 7; ++j){
for(int i = 0; i &lt; 7; ++i){
if(i != j){
if(allCards[j].getRank() == allCards[i].getRank()){
pairCount[j]++;
}
}
}
if(pairCount[j] == 4){
return FOURKIND;
} else if(pairCount[j] == 3){
threeKind++;
} else if(pairCount[j] == 2){
pair++;
}
}

//*************check for full house**********************
if((threeKind == 3 &amp;&amp; (pair == 2 || pair == 4)) || threeKind == 6){
return FULLHOUSE;
}

//*************check for flush***************************
if(flush){
return FLUSH;
}

//**************check for straight*******************
sort(allCards.begin(), allCards.end()); //now sort by rank to check for straight
int straightCount = 1, straightIndex = 6;
c = allCards[6];
for(int i = 5; i &gt;= 0; --i){
//loop through the array backwards, checking the highest card first
if(c.getRank() - allCards[i].getRank() == 1){ //next in the straight
straightCount++;
//if there is not a pair, reset straight counts and straightflush counts
} else if(c.getRank() != allCards[i].getRank()){
straightCount = 1;
straightIndex = i;
}
if(straightCount &gt;= 5){ //straight!
return STRAIGHT;
}
c = allCards[i];
}

//*************check for trips**********************
if(threeKind == 3){
return THREEKIND;
}

//************check for two pair********************
if(pair == 4 || pair == 6){
return TWOPAIR;
}

//***********check for one pair*********************
if(pair == 2){
return ONEPAIR;
}

//***************HIGH CARD***************
return HIGHCARD;
} </pre><hr />

[/ QUOTE ]
Reply With Quote
  #15  
Old 07-26-2006, 09:20 AM
Shroomy Shroomy is offline
Senior Member
 
Join Date: Apr 2006
Location: Miami FLA
Posts: 465
Default Re: Algorithm for Figuring out Your Hold\'em Hand

[ QUOTE ]
Also, I just want an algorithm, not actual code. I'm really just trying to keep my programing skills sharpened during the summer.

[/ QUOTE ]

step 1 create a table of all valid hands starting with lowest (2,3,4,5,7) so it returns 1 and ending with highest (royal flush) so it returns 7462

step 2
if the score is 1-1277 its a highcard hand (no pair)
if the score is 1278 - 4137 its a one pair hand
etc..
if the score is 7452 - 7462 it is a straight flush

You can get more detailed if you want like 1124-1277 is an Ace high hand.

and look here http://forumserver.twoplustwo.com/showfl...e=0#Post6652490
Reply With Quote
  #16  
Old 07-26-2006, 09:22 AM
Shroomy Shroomy is offline
Senior Member
 
Join Date: Apr 2006
Location: Miami FLA
Posts: 465
Default Re: Algorithm for Figuring out Your Hold\'em Hand

[ QUOTE ]
In case anyone was wondering... here is the code I came up with.

[/ QUOTE ]

I'm not trying to criticize, but that is insanely inefficient.
Reply With Quote
  #17  
Old 07-26-2006, 03:32 PM
mykey1961 mykey1961 is offline
Senior Member
 
Join Date: Oct 2005
Posts: 249
Default Re: Algorithm for Figuring out Your Hold\'em Hand

Here is the main guts of a hand evaluator I wrote.
Most of the "labor" was in creating the tables, which I have elsewhere in the code as constants.

It takes a 64 bit value (each card is represented by a bit)

This code works for 5, 6, and 7 cards.
It returns a 24 bit value (top 4 = hand type) and (4 per card) represent the specific hand.

0x55432E represents a 5 high straight
0x5EDCBA represents a A high straight
0x796000 represents a Full House 9's over 6's
0x175432 represents the worst possible hand.
etc.

If there is interest, I can explain what the code is doing each step of the way.

<font class="small">Code:</font><hr /><pre>
function GetScore(Hand : THand) : integer;
asm
push esi
push edi
push edx
push ecx
push ebx

mov esi,DWORD[Hand.SpadesAndHearts]
mov ecx,DWORD[Hand.DiamondsAndClubs]
mov eax,$FFFF
mov ebx,esi
mov edx,ecx
and esi,eax
shr ebx,16
and ecx,eax
shr edx,16

xor eax,eax
or eax,DWORD[esi*4+FiveRankTable]
or eax,DWORD[ebx*4+FiveRankTable]
or eax,DWORD[ecx*4+FiveRankTable]
or eax,DWORD[edx*4+FiveRankTable]
jz @NoFlush
@IsFlush:
cmp eax,Code_Straight
jl @NoStraightFlush
add eax,Code_StraightFlush-Code_Straight
jmp @Done
@NoStraightFlush:
add eax,Code_Flush-Code_HighCard
jmp @Done

@NoFlush:
mov edi,esi
and edi,ebx
or esi,ebx
mov ebx,edi

and edi,ecx
mov eax,ecx
and eax,esi
or ebx,eax
or esi,ecx
mov ecx,edi

and edi,edx
mov eax,ebx
and eax,edx
or ecx,eax
mov eax,esi
and eax,edx
or ebx,eax
or esi,edx
mov edx,edi

test edx,edx
jz @NoQuads
xor esi,edx
mov eax,Code_Quads
or eax,DWORD[edx*4+Put1In1]
or eax,DWORD[esi*4+Put1In2]
jmp @Done

@NoQuads:
test ecx,ecx
jz @NoFullHouse
xor ebx,DWORD[ecx*4+Get1Bit]
test ebx,ebx
jz @NoFullHouse
mov eax,Code_FullHouse
or eax,DWORD[ecx*4+Put1In1]
or eax,DWORD[ebx*4+Put1In2]
jmp @Done

@NoFullHouse:
mov eax,DWORD[esi*4+FiveRankTable]
cmp eax,Code_Straight
jg @Done
test ecx,ecx
jz @NoTrips
xor esi,ecx
mov eax,Code_Trips
or eax,DWORD[ecx*4+Put1In1]
or eax,DWORD[esi*4+Put1_2In2_3]
jmp @Done

@NoTrips:
mov edi,DWORD[ebx*4+Put1_2In1_2]
test edi,edi
jz @NoTwoPair
xor esi,DWORD[ebx*4+Get1_2Bit]
mov eax,Code_TwoPair
or eax,edi
or eax,DWORD[esi*4+Put1In3]
jmp @Done

@NoTwoPair:
test ebx,ebx
jz @Done
xor esi,ebx
mov eax,Code_OnePair
or eax,DWORD[ebx*4+Put1In1]
or eax,DWORD[esi*4+Put1_3In2_4]

@Done:
pop ebx
pop ecx
pop edx
pop edi
pop esi
end;
</pre><hr />
Reply With Quote
  #18  
Old 07-26-2006, 04:06 PM
jukofyork jukofyork is offline
Senior Member
 
Join Date: Sep 2004
Location: Leeds, UK.
Posts: 2,551
Default Re: Algorithm for Figuring out Your Hold\'em Hand

[ QUOTE ]
Here is the main guts of a hand evaluator I wrote.
Most of the "labor" was in creating the tables, which I have elsewhere in the code as constants.

It takes a 64 bit value (each card is represented by a bit)

This code works for 5, 6, and 7 cards.
It returns a 24 bit value (top 4 = hand type) and (4 per card) represent the specific hand.

0x55432E represents a 5 high straight
0x5EDCBA represents a A high straight
0x796000 represents a Full House 9's over 6's
0x175432 represents the worst possible hand.
etc.

If there is interest, I can explain what the code is doing each step of the way.

<font class="small">Code:</font><hr /><pre>
function GetScore(Hand : THand) : integer;
asm
push esi
push edi
push edx
push ecx
push ebx

mov esi,DWORD[Hand.SpadesAndHearts]
mov ecx,DWORD[Hand.DiamondsAndClubs]
mov eax,$FFFF
mov ebx,esi
mov edx,ecx
and esi,eax
shr ebx,16
and ecx,eax
shr edx,16

xor eax,eax
or eax,DWORD[esi*4+FiveRankTable]
or eax,DWORD[ebx*4+FiveRankTable]
or eax,DWORD[ecx*4+FiveRankTable]
or eax,DWORD[edx*4+FiveRankTable]
jz @NoFlush
@IsFlush:
cmp eax,Code_Straight
jl @NoStraightFlush
add eax,Code_StraightFlush-Code_Straight
jmp @Done
@NoStraightFlush:
add eax,Code_Flush-Code_HighCard
jmp @Done

@NoFlush:
mov edi,esi
and edi,ebx
or esi,ebx
mov ebx,edi

and edi,ecx
mov eax,ecx
and eax,esi
or ebx,eax
or esi,ecx
mov ecx,edi

and edi,edx
mov eax,ebx
and eax,edx
or ecx,eax
mov eax,esi
and eax,edx
or ebx,eax
or esi,edx
mov edx,edi

test edx,edx
jz @NoQuads
xor esi,edx
mov eax,Code_Quads
or eax,DWORD[edx*4+Put1In1]
or eax,DWORD[esi*4+Put1In2]
jmp @Done

@NoQuads:
test ecx,ecx
jz @NoFullHouse
xor ebx,DWORD[ecx*4+Get1Bit]
test ebx,ebx
jz @NoFullHouse
mov eax,Code_FullHouse
or eax,DWORD[ecx*4+Put1In1]
or eax,DWORD[ebx*4+Put1In2]
jmp @Done

@NoFullHouse:
mov eax,DWORD[esi*4+FiveRankTable]
cmp eax,Code_Straight
jg @Done
test ecx,ecx
jz @NoTrips
xor esi,ecx
mov eax,Code_Trips
or eax,DWORD[ecx*4+Put1In1]
or eax,DWORD[esi*4+Put1_2In2_3]
jmp @Done

@NoTrips:
mov edi,DWORD[ebx*4+Put1_2In1_2]
test edi,edi
jz @NoTwoPair
xor esi,DWORD[ebx*4+Get1_2Bit]
mov eax,Code_TwoPair
or eax,edi
or eax,DWORD[esi*4+Put1In3]
jmp @Done

@NoTwoPair:
test ebx,ebx
jz @Done
xor esi,ebx
mov eax,Code_OnePair
or eax,DWORD[ebx*4+Put1In1]
or eax,DWORD[esi*4+Put1_3In2_4]

@Done:
pop ebx
pop ecx
pop edx
pop edi
pop esi
end;
</pre><hr />

[/ QUOTE ]
Sweet to see some assembler! I think, sadly, it's a dieing art thesedays though... [img]/images/graemlins/frown.gif[/img]

Can I ask why you coded this up in asm? I remember the days when I could gain quite alot from hand coding asm routines (z80, 600x0, 8086, 80x86, ...) but thesedays I just can't beat the modern optimizing compilers; they know way more about all the pipelines and t-state timings than I ever will, and most times they can outperform my hand coded asm routines hand down.

I hope asm doesn't die out (as M$ would hope), as I think there is still alot to be gained from learning low level coding.

Just my 2c - Juk [img]/images/graemlins/smile.gif[/img]
Reply With Quote
  #19  
Old 07-26-2006, 06:28 PM
mykey1961 mykey1961 is offline
Senior Member
 
Join Date: Oct 2005
Posts: 249
Default Re: Algorithm for Figuring out Your Hold\'em Hand

Most of what I write is in Delphi (Pascal) and at times it doesn't seem to be the most efficient, so to keep all the computation (bit twiddling) in the registers I had to resort to asm.

Likewise, I got my start with 6800, 6502, 8080, then advanced to the Z80 [img]/images/graemlins/smile.gif[/img]
Reply With Quote
  #20  
Old 07-26-2006, 07:44 PM
jukofyork jukofyork is offline
Senior Member
 
Join Date: Sep 2004
Location: Leeds, UK.
Posts: 2,551
Default Re: Algorithm for Figuring out Your Hold\'em Hand

[ QUOTE ]
Likewise, I got my start with 6800, 6502, 8080, then advanced to the Z80 [img]/images/graemlins/smile.gif[/img]

[/ QUOTE ]
Hehe, I'm too young to remember much before the Z80... I do remember using "BBC Micros" and an "Acorn Electron" when I was a small child (both used 6502's I think).

I started on a ZX-Spectrum, and soon worked out that if I wanted to do anything fast then interpreted BASIC really sucked, and I was gonna have to use "machine code"! [img]/images/graemlins/confused.gif[/img]

Still, I think what I learn way back then, when computers and coding were so much simpler, has helped me more than I can put into words...

Juk [img]/images/graemlins/smile.gif[/img]
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 04:05 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.