Does anyone know a fast algorithm for evaluating 7 card poker hands? Something which is more efficient than simply brute-force checking a every 21 5-card combination of hands fr
I wrote one in JavaScript. The core evaluating method uses only bit manipulations so is extremely fast. With this in mind, looking at 21 combinations is still very fast. The only time we need to go deeper is when a tie occurs. When this happens, we need to look into more details to see which 5 card hand is actually the best. Here is the solution I came up with:
hands=["4 of a Kind", "Straight Flush", "Straight", "Flush", "High Card",
"1 Pair", "2 Pair", "Royal Flush", "3 of a Kind", "Full House" ];
var A=14, K=13, Q=12, J=11, _ = { "♠":1, "♣":2, "♥":4, "♦":8 };
//Calculates the Rank of a 5 card Poker hand using bit manipulations.
function rankPokerHand(cs,ss) {
var v, i, o, s = 1<<cs[0]|1<<cs[1]|1<<cs[2]|1<<cs[3]|1<<cs[4];
for (i=-1, v=o=0; i<5; i++, o=Math.pow(2,cs[i]*4)) {v += o*((v/o&15)+1);}
v = v % 15 - ((s/(s&-s) == 31) || (s == 0x403c) ? 3 : 1);
v -= (ss[0] == (ss[1]|ss[2]|ss[3]|ss[4])) * ((s == 0x7c00) ? -5 : 1);
document.write("Hand: "+hands[v]+((s == 0x403c)?" (Ace low)":"")+"<br/>");
}
//Royal Flush
rankPokerHand( [ 10, J, Q, K, A], [ _["♠"], _["♠"], _["♠"], _["♠"], _["♠"] ] );
Explanation Here
Demo Here
I developed a simulator Texas hold'em and during this development I found the number of 7462 unique combinations (52 - 5/5 cards) on the flop. In turn, this number drops to 6075 (5/6) and in the river to 4824 (5/7). This is because 1 or 2 cards are irrelevant in classifying the poker hand. An example is: 76543QK = 7654332 a straight (3 to 7)
My simulator is called Easy Poker and is available in my site http://crvltda.webs.com
Ref. Pokersoftware.com/forum
I've created a testbed for poker evaluators in C here. Of the evaluators I tested, the poker-eval library was the winner. Steve Brecher's Holdem Showdown was also quite fast and had significantly less memory requirements. My own ACE_Eval held it's own.
I'd welcome help adding other evaluators, and contributions of test results from other machines.
I think you should do the 21 combinations and use some kind of 7462 table. 1st: any 7 cards have 21 different 5 cards combinations 2nd: every possible final poker hands (2.598.960) represents one of 7462 different kind of hands so, it´s easy.
You just have to look at every 21 combinations of your cards and, for each one, see the ranking of 7462 ranking table. http://www.sendspace.com/file/pet0dd
Then, for each 7 cards you will have 21 different rankings from this 7462 table i made. The highest ranking of 21 combinations is the one you want to know.
To understand the table: In every line you have the 5 card hand (Z for suited, Y non-suited) and you have the ranking of it. That´s only you need. I give you the table and an example algorithm. It´s not really the code. It´s visual basic format and i wrote it now. probably doesn´t work but you should understand. The code would be something like this:
'############### 1st: Define your hand, for example "2c2d2h2s3c3h3s" #############################################################################################
Dim mycard As New ArrayList
mycard(1).Add("2c")
mycard(2).Add("2d")
mycard(3).Add("2h")
mycard(4).Add("2s")
mycard(5).Add("3c")
mycard(6).Add("3h")
mycard(7).Add("3s")
mycard.Sort() '################# you need to sort in alphabeticall order to match it later with 7462 table #############################################
' ################## 2nd: Let´s transform it to every kind of 5 cards combinations (21). It will also preserve the alphabeticall order ##################################
Dim myHand5 As String = ""
Dim suited as String = ""
Dim ranking as Integer = 0
Dim myranking as Integer = 7462
Dim mystring as String = ""
For cicle1 = 0 to 2
For cicle2 = cicle1 + 1 to 3
For cicle3 = cicle3 + 1 to 4
For cicle4 = cicle3 + 1 to 5
For cicle5 = cicle4 + 1 to 6
myhand5 = left(mycard(cicle1),1) & left(mycard(cicle2),1) & left(mycard(cicle3),1) & left(mycard(cicle4),1) & left(mycard(cicle5),1)
suited = left(mycard(cicle1),2) & left(mycard(cicle2),2) & left(mycard(cicle3),2) & left(mycard(cicle4),2) & left(mycard(cicle5),2)
if suited = "ccccc" or suited = "ffffffffd" or suited = "hhhhh" or suited = "sssss" then myhand5 = myhand5 & "Z" Else myhand5 = myhand5 & "Y"
ranking = 0
FileOpen (1, "7462.txt", Input)
Do
ranking = ranking + 1
Input(1, mystring)
Input(1, ranking)
If mystring = myhand5 Then
If ranking < myranking then myrankin = ranking
End If
Loop Until EOF(1)
FileClose(1)
Next cicle5
Next cicle4
Next cicle3
Next cicle2
Next cicle1
Final ranking is myranking variable. You should know your hand in less than a second. And also is good to compare with other hands, because you have the ranking value not the name of it. And if you want to do something with poker algorithms, this is where you should start. With ranking values everything is quick and easy.
Note: I´m not a programmer. I am a wanna be. I understand some visual basic functions. I whish i knew how to make real programs. If the algorithm works, please leave a comment. If you want it to be very very fast, i don´t know how to do it. I whish i have an ultra fast algorithm that allows me check (in real time) my odds against any opponents in every stage of the game. I tried many algorithms to calculate my odds at the flop in real time but the fastest i can is 30 seconds. Now, i can calculate my odds at the flop in 3 seconds but i use a 150 gigabytes database with many things pre-calculated. If you want to know your odds in real time you should have many things pre-calculated. That´s how i did.
This site lists a bunch of Poker Hand Evaluator libraries and gives a few details about each of them. Most of them are for 5 card hands, but there is at least one for a 7 card hand called The Snezee7 Evaluator. Plus the site give a great overview of the different techniques and algorithms used to analyze poker hands quickly.
I've used the Keith Rule C# Port of the Pokersource Evaluator in a few different poker projects and think that it is an excellent library. There are many clever tricks you can use to make really fast hand evaluators, but writing the code is a lot of work and I would highly suggest using an existing library.
Glad you asked :) Yes, here's a brand new solution that may be just the ticket:
Code: http://code.google.com/p/specialkpokereval/
Blog: http://specialk-coding.blogspot.com/2010/04/texas-holdem-7-card-evaluator_23.html
A commercial-grade evolution of this evaluator is available for the iPhone/iPod Touch via iTunes Store. It's called "Poker Ace".
An excellent summary of various solutions complete with links is found on James Devlin's blog "Coding The Wheel".
One evaluator not yet discussed there is Klaatu's.
Good luck!