7 Card Poker Hand Evaluator

2020-05-11 09:56发布

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

9条回答
一纸荒年 Trace。
2楼-- · 2020-05-11 10:48

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.

查看更多
来,给爷笑一个
3楼-- · 2020-05-11 10:51

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.

查看更多
闹够了就滚
4楼-- · 2020-05-11 10:53

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

查看更多
登录 后发表回答