Algorithm to give a value to a 5 card Poker hand

好久不见. 提交于 2019-11-30 22:30:13

There are 10 recognized poker hands:

9 - Royal flush
8 - Straight flush (special case of royal flush, really)
7 - Four of a kind
6 - Full house
5 - Flush
4 - Straight
3 - Three of a kind
2 - Two pair
1 - Pair
0 - High card

If you don't count suit, there are only 13 possible card values. The card values are:

2 - 0
3 - 1
4 - 2
5 - 3
6 - 4
7 - 5
8 - 6
9 - 7
10 - 8
J - 9
Q - 10
K - 11
A - 12

It takes 4 bits to code the hand, and 4 bits each to code the cards. You can code an entire hand in 24 bits.

A royal flush would be 1001 1100 1011 1010 1001 1000 (0x9CBA98)

A 7-high straight would be 0100 0101 0100 0011 0010 0001 (0x454321)

Two pair, 10s and 5s (and an ace) would be 0010 1000 1000 0011 0011 1100 (0x28833C)

I assume you have logic that will figure out what hand you have. In that, you've probably written code to arrange the cards in left-to-right order. So a royal flush would be arranged as [A,K,Q,J,10]. You can then construct the number that represents the hand using the following logic:

int handValue = HandType; (i.e. 0 for high card, 7 for Four of a kind, etc.)
for each card
    handValue = (handValue << 4) + cardValue  (i.e. 0 for 2, 9 for Jack, etc.)

The result will be a unique value for each hand, and you're sure that a Flush will always beat a Straight and a king-high Full House will beat a 7-high Full House, etc.

Normalizing the hand

The above algorithm depends on the poker hand being normalized, with the most important cards first. So, for example, the hand [K,A,10,J,Q] (all of the same suit) is a royal flush. It's normalized to [A,K,Q,J,10]. If you're given the hand [10,Q,K,A,J], it also would be normalized to [A,K,Q,J,10]. The hand [7,4,3,2,4] is a pair of 4's. It will be normalized to [4,4,7,3,2].

Without normalization, it's very difficult to create a unique integer value for every hand and guarantee that a pair of 4's will always beat a pair of 3's.

Fortunately, sorting the hand is part of figuring out what the hand is. You could do that without sorting, but sorting five items takes a trivial amount of time and it makes lots of things much easier. Not only does it make determining straights easier, it groups common cards together, which makes finding pairs, triples, and quadruples easier.

For straights, flushes, and high card hands, all you need to do is sort. For the others, you have to do a second ordering pass that orders by grouping. For example a full house would be xxxyy, a pair would be xxabc, (with a, b, and c in order), etc. That work is mostly done for you anyway, by the sort. All you have to do is move the stragglers to the end.

As you have found, if you add together the values of the cards in the way you have proposed then you can get ambiguities.

100000 + 4^1 + 6^2 + 11^1 + 13^1 = 100064
100000 + 3^1 + 4^1 + 7^2 + 8^1 = 100064

However, addition is not quite the right tool here. You are already using ^ which means you're partway there. Use multiplication instead and you can avoid ambiguities. Consider:

100000 + (4^1 * 6^2 * 11^1 * 13^1)
100000 + (3^1 * 4^1 * 7^2 * 8^1)

This is nearly correct, but there are still ambiguities (for example 2^4 = 4^2). So, reassign new (prime!) values to each card:

Ace => 2
3 => 3
4 => 5
5 => 7
6 => 11
...

Then, you can multiply the special prime values of each card together to produce a unique value for every possible hand. Add in your value for type of hand (pair, full house, flush, etc) and use that. You may need to increase the magnitude of your hand type values so they stay out of the way of the card value composite.

The highest value for a card will be 14, assuming you let non-face cards keep their value (2..10), then J=11, QK, A=14.

The purpose of the scoring would be to differentiate between hands in a tie-breaking scenario. That is, "pair" vs. "pair." If you detect a different hand configuration ("two pair"), that puts the scores into separate groups.

You should carefully consult your requirements. I suspect that at least for some hands, the participating cards are more important than non-participating cards. For example, does a pair of 4's with a 7-high beat a pair of 3's with a queen-high? (Is 4,4,7,3,2 > 3,3,Q,6,5?) The answer to this should determine an ordering for the cards in the hand.

Given you have 5 cards, and the values are < 16, convert each card to a hexadecimal digit: 2..10,JQKA => 2..ABCDE. Put the cards in order, as determined above. For example, 4,4,7,3,2 will probably become 4,4,7,3,2. Map those values to hex, and then to an integer value: "0x44732" -> 0x44732.

Let your combo scores be multiples of 0x100000, to ensure that no card configuration can promote a hand into a higher class, then add them up.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!