Zigpokerhands

zigpokerhands is a program that uses zigdeck to evaluate five cards to determine if it matches a poker hand

I got a lot of help with this from ChatGPT and people on the Internet, including this forum. :slight_smile: Thank you.

Locally and in the GitHub CI, I’m testing with a recent version of Zig from master.

Feedback is welcome but I’m not sure how long it will take for me to implement and understand suggestions. I sometimes have to take extended breaks from the computer due to nerve pain (that’s one reason I got a lot of code from ChatGPT… I’m interested in Zig but can’t spend as much time on the computer right now as I want). Though any feedback I’m sure will also be helpful to other folks who are searching threads. :wink:

Here’s some sample output:

Evaluating 1000000 hands...

                                   Pair: 468472
                           ThreeOfAKind: 20702
                               Straight: 4201
                                  Flush: 2585
                              FullHouse: 1359
                            FourOfAKind: 222
                          StraightFlush: 20
                             RoyalFlush: 1
3 Likes

Oh, I forgot to mention, if anyone wants to exercise their zig skills, feel free to make a pull request on either the zigpokerhands or zigdeck repo. Open a ticket first though, so people (including myself) won’t try to duplicate what you’re working on and submit a PR before you submit yours.

I implemented a poker calculator many years ago, here are some things that I learned.
You can get excellent performance by representing cards as bits. A hand can be composed of 4 u13, each one representing one suit. Bit 0 represents card 2 and bit 12 represents an Ace. Testing for a flush can be done by checking if the pop count of a suit is at least 5. Testing for a straight can be done by or’ing all suits and checking if the set bits are contiguous. Checking for a pair can be done by and’ing each pair of suits and checking if any of these is different from 0.
If you want to compare hands to determine the winner, you don’t want to test each hand agaisn’t each other hand, as that would result in combinatorial explosion. It’s better to set a score. Then it’s just a matter of finding the highest score, which is linear. Here’s the best way that I found for this: consider a hexadecimal number with 6 digits. Since there are 9 possible hand types, you can assign an exclusive number for each. 0 is a high card, 1 is a pair and so forth. The higher the number, the stronger the hand. If you put this number in the highest order digit (6th digit), a hand with a stronger hand type will always have a score higher than a weaker hand. For example, a pair could be assigned number 0x110000 (the most significant 1 represents a pair), while a high card could be assigned number 0x0BA987 (the 0 represents a high card). The following digits you fill by assigning the strongest cards that participate in the hand. Since there are 13 cards, you can also assign an exclusive digit for each. Here are some examples:

Hand A: 2 of spades, 2 of hearts, 3 of spades, 3 of hearts, king of hearts, queen of spades, 7 of clubs
(2 cards in hand, 5 on the table, it doesn’t matter which oneis which).

The hand type is two pairs, so the most significant digit is 2. The first tie breaker would be the 3, so we assign it number 1. The second tie breaker would be the 2, so we assign it number 0. The last tie breaker would be the king, number 0xB. The other cards don’t participate, so we pad the remaining two digits with 0. Te score would be 0x210B00

Hand B: 8 of diamonds, 4 of hearts, 3 of spades, 3 of hearts, king of hearts, queen of spades, 7 of clubs
(2 cards in hand, 5 on the table, it doesn’t matter which one is which).

The hand type is one pair, digit 1. The first tie breaker is 3, digit 1. Second tie breaker is king, digit 0xB. Third tie breaker is queen, digit 0xA. Fourth tie breaker is 8, digit 6. Other cards don’t participate, so the last digit is 0. The score is 0x11BA80

Since 0x210B00 > 0x11BA80, hand A wins.

2 Likes

That sounds like a very interesting and efficient approach! I can’t claim to understand though; I never learned anything about bit-level development (or whatever might be a more appropriate term in this case). I’ll bookmark your post though and hopefully can try something like that some day. Thank you for sharing @LucasSantos91

In the near future, I think I’d like to split zigpokerhands and make a library from it that can compare multiple hands consisting of five, size, or seven cards and determine the best hand (i.e., the best 5 cards if the hand consists of 6 or 7 cards).

A quick note: if you are math oriented, you can think of (unsigned) integers as small sets (as in Set Theory), with support for efficient computation of set operations (union, intersection, complement, etc). If this sounds like it would be useful for your use case (and it is, as @LucasSantos91 describes), you might find it interesting to go the suggested way.

3 Likes

I’m not math-oriented, but I am intrigued and like an occasional challenge. A friend of mine suggested this link to help get me started.

1 Like