Algorithm to give a value to a 5 card Poker hand

后端 未结 3 482
-上瘾入骨i
-上瘾入骨i 2021-01-05 01:43

I am developing a poker game as college project and our current assignment is to write an algorithm to score a hand of 5 cards, so that the scores of two hands can be compar

相关标签:
3条回答
  • 2021-01-05 02:26

    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.

    0 讨论(0)
  • 2021-01-05 02:28

    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.

    0 讨论(0)
  • 2021-01-05 02:45

    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.

    0 讨论(0)
提交回复
热议问题