7 Card Poker Hand Evaluator
Asked Answered
A

9

40

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 from a set of 7.

Cheers,

Pete

Aegeus answered 13/5, 2010 at 19:59 Comment(5)
Good question, but I think you're better off just checking the 21 combinations instead of trying to figure out some crazy gimmick to shortcut.Interlaken
@David Actually, nothing could be further from the truth. People have put a lot of effort into writing fast 7 card evaluators. When you want to do millions of hands a second, speed becomes important.Decani
@David: There are far better ways that are easier to read and require NO sorting whatsoever. They're also several orders of magnitude faster for it. An example is - ahem - found here: code.google.com/p/specialkpokereval.Transcendence
I wrote my own in Java as an exercise (I wanted to re-invent the wheel for the sake of it). It's documented and it's exactly what you are describing. You have lots of answers already but if you are programming in Java, it could be more relevant to you. Reply to this comment and I'll create a new answer linking it. If it's not Java, I guess I won't be more interesting for you than any of the already linked.Uganda
I wrote a java program that checks all 133 million 7-card hands in 5 seconds: codeproject.com/Articles/1068755/… It's an ongoing project so I hope it will get even faster.Adduce
A
14

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.

Antisana answered 13/5, 2010 at 20:25 Comment(5)
Note that Snezee7 requires a 266 MB lookup table.Interlaken
It does... but that is how you get a fast hand evaluator (lots of pre-computation). The Two Plus Two evaluator uses a similar approach to evaluate 7 card hands using a 123 MB lookup table. For 5 card hands the lookup tables are much smaller.Antisana
shameless plug - While not as fast as some of the ones above, I have one that does ~70M hands/s using no tables at all here: github.com/ashelly/ACE_eval.Theolatheologian
@polarysekt Sadly the Coding the Wheel website has been down for a few months. Not sure if it is coming back or not, but for now you can find the details for both links in the WayBack Machine using web.archive.org/web/20140625212722/http://codingthewheel.com/…Antisana
Another plug: lcrocker.github.io/onejoker/cardlib has bindings for several languages. It's 5-card evaluator is faster than any previous one, and it's seven-card evaluator is comparable to the best, and requires only 1Mb of tables.Baptist
Y
33

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

Yeargain answered 9/11, 2012 at 20:59 Comment(3)
lots of effort put into this one! +1 :)Athenaathenaeum
He's a witch! Awesome article.Cystocele
There is a bug in this code - if you have a straight with an Ace as the low card (e.g.A♣ 2♦ 3♦ 4♠ 5♥ 6♦ K♥ ) then it incorrectly picks the lower straight. In this example the 6♦ high straight should be best. This is because it is giving extra weight to the Ace but in this case its wrong to do so as its not the high straight but rather the lower straight. see imgur.com/a/e9wGRFranconian
A
14

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.

Antisana answered 13/5, 2010 at 20:25 Comment(5)
Note that Snezee7 requires a 266 MB lookup table.Interlaken
It does... but that is how you get a fast hand evaluator (lots of pre-computation). The Two Plus Two evaluator uses a similar approach to evaluate 7 card hands using a 123 MB lookup table. For 5 card hands the lookup tables are much smaller.Antisana
shameless plug - While not as fast as some of the ones above, I have one that does ~70M hands/s using no tables at all here: github.com/ashelly/ACE_eval.Theolatheologian
@polarysekt Sadly the Coding the Wheel website has been down for a few months. Not sure if it is coming back or not, but for now you can find the details for both links in the WayBack Machine using web.archive.org/web/20140625212722/http://codingthewheel.com/…Antisana
Another plug: lcrocker.github.io/onejoker/cardlib has bindings for several languages. It's 5-card evaluator is faster than any previous one, and it's seven-card evaluator is comparable to the best, and requires only 1Mb of tables.Baptist
C
8

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!

Carnay answered 13/5, 2010 at 19:59 Comment(2)
I've added your evaluator to my roundup. I'd appreciate any feedback.Theolatheologian
@Theolatheologian Your ACE evaluator is pretty freaking amazing. I've been dreaming of porting it to the GPU for years... but sadly I don't play poker anymore!Fasciation
C
5

I developed an algorithm for 7-card hand evaluation without iterating all 21 combinations.

Basically, it splits the 7-card hand into two categories: flush and not a flush. If it's a flush, it would be easy to look up the value in a table of 8192 entries. If it's not a flush, it'll run a hash function with techniques of dynamic programming, and then look up the value in a hash table of 49205 entries.

If you are interested, please check my work at github.

https://github.com/HenryRLee/PokerHandEvaluator

Carthusian answered 6/3, 2016 at 13:6 Comment(2)
you evaluator can greatly improve performance if you calculate quinary after check of flush is done rather than before if(suit-suit_hash]) additionally since len in always 13 and k is always 7 flattening the loops saves another 15% on averageNonplus
@SiddharthChabra Good idea. Thanks for the tips. You are welcome to submit a pull request if you like.Carthusian
O
2

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 = "ddddd" 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.

Organelle answered 21/11, 2012 at 3:57 Comment(0)
T
2

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.

Theolatheologian answered 18/5, 2015 at 1:50 Comment(2)
I had a good look at Steve Brecher's evaluator, but I'm having a hard time extracting card values from his 0x0V0RRRRR eval result. Can you add a more detailed decoder in the BHS section of your benchmarks?Sumerlin
I will try to get to that, but in the meantime: There are up to 5 'R' nibbles, where 0..C represents '2'..'Ace'. They represent the values of the cards that make up the hand rank. Trailing 0s are ignored. You need to look at the rank to determine how many values to pull out. So for 4 Aces with a 7 kicker, you would have C5000. For a Full House Kings over 3s, you get B1000 . Two Pair, 8s and 4s with a Queen kicker is 62A00. And so forth. A High-Card hand would use all 5 nibbles. ACE_Eval.h uses a similar representation. See ACE_decode() for one way to get the winning cards.Theolatheologian
O
0

Of course, if you want to do it very fast. The algorithm i put before is too slow.

The table7462 shoul be in an array, not in a file.

Then, you should precalculate every different 7cards hands and store it to a database. There are 133.784.560 different 7cards combinations.

You should use this format (alphabeticall order):

"2c2d2h2s3c3d3h" and rank it

Store every 133.784.560 different combinations. You do 52C7 cicles, rank it and store it in a database. Maybe in a few days you have it ready. When you have it ready, you don´t need 21 combinations anymore, just put your hand sorted alphabetically and search for it in your database.

If you do that, you´ll see that you can calculate your odds against your opponents in real time whenever you need.

Believe me. I am not a programmer and i can do it. I know my odds at the flop in 3 seconds.

Organelle answered 21/11, 2012 at 4:23 Comment(0)
P
0

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

Pommard answered 21/1, 2013 at 22:49 Comment(0)
M
0

May I recommend https://github.com/chenosaurus/poker-evaluator/

It is written in JavaScript and uses a 128 MB HandRanks.dat file.

The code is just a few lines and very easy to port to any other language.

Module answered 4/7, 2018 at 2:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.