0

I'm making a quick and dirty poker game in python, and am having trouble determining which player wins the hand. I have functions that deal cards, determine the "value" of the hand in the way that 0-8 correspond to high card - straight flush, and then the key pieces of what makes each hand unique.

What I'm having trouble is determining who wins when there are two or more players with the same hand type (pair,two pair, etc), and even worse when they have the same pair, and I have to go down and look at the kickers.

I'm having trouble determining a good way to store the data, and compare it all together as I need. I don't want to include all of my functions to check hand values and whatnot as it would get way too long. I'm really interested in people's thoughts on how to store and compare this data, especially what is mentioned about hands with similar values (the stuff in bold)

Each Player's hand is represented by a dictionary entry, keyed by player number in the form

mydict = {(1 :(2,'Spades)), (2 :(3,'Diamonds')), etc}

players = 5
# Creates deck of cards and deals to each player
Cards = Shuffle_Deck(Suits,Values,1)
All_Players, Cards = deal_hand(players,5,Cards)

# scores and orders hands
def order_hands(All_Players):
    rank_hands = []
    for i in range(1,len(All_Players)+1):
        rank_hands.append([i,score_hand(All_Players[i],printhand=False,printvalue=False)])
    sorted_hands = rank_hands[:]
    sorted_hands.sort(key=lambda x: x[1][0],reverse=True)
    return sorted_hands

Sorted_Hands = order_hands(All_Players)
#print Sorted_Hands
def who_Wins(Sorted_Hands):
    Tied_Hands = []
    winning_index = Sorted_Hands[0][1][0]
    for i in range(len(Sorted_Hands)):
        if Sorted_Hands[i][1][0] == winning_index:
#            print Sorted_Hands[i]
            Tied_Hands.append([Sorted_Hands[i][0],Sorted_Hands[i][1][1:]])

    return winning_index,Tied_Hands

winning_index,Tied_Hands = who_Wins(Sorted_Hands)
Tied_Hands.sort(key=lambda x: x[1], reverse=True)
print Tied_Hands
for i in range(len(Tied_Hands)):
    vals = [val for (val,suit) in All_Players[Tied_Hands[i][0]]]
    print 'vals',sorted(vals,reverse=True)
#for hands in Tied_Hands:
#    if
print Tied_Hands[0][0]
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
KevinShaffer
  • 760
  • 5
  • 14
  • 26
  • Google "poker hand evaluator" and you'll find lots of fast algorithms, including my [ojcardlib](http://github.com/lcrocker/ojcardlib). But they all rely on much simpler representations of cards and hands. In particular, using strings for suits will cripple your code. See also http://etceterology.com/blog/2013/5/23/representing-playing-cards-in-software – Lee Daniel Crocker Jun 15 '13 at 13:28

2 Answers2

4

Here's an example I wrote:

http://www.paulgriffiths.net/program/python/pcards.php

The _set_score() method is the one that does the trick. The solution I came up with was to score the components on the hands in lists. For instance, for a full house, the first item in the list is a score for the overall hand (e.g. full house beats a pair, straight beats three of a kind), the second item in the list is the rank of the three of a kind, and the third item in the list is the rank of the pair. That way, you can compare any hand very simply by just comparing one hand to another (i.e. one list to another) with the regular <, >, <=, >= operators, and Python does all the hard work for you. For a full house, when you compare the lists, Python will look at each item in turn. If both hands are full houses, it'll compare the threes of a kind, and the highest three will win. If the threes are the same, it'll compare the pairs, and the highest pair will win. If the threes and the pairs are equal, then both hands are equal. This method works generally and allows you to compare any two hands simply by comparing the lists.

Crowman
  • 25,242
  • 5
  • 48
  • 56
  • I'll upvote this as good-looking code for pedagogical purposes. OP probably doesn't need the industrial-strength complex fast poker hand evaluators used for doing simulations. – Lee Daniel Crocker Jun 15 '13 at 13:35
  • I upvoted this answer, as it was good. But in all honesty it's too confusing for me, and I ended up using the other above answer, but thanks! – KevinShaffer Jun 15 '13 at 14:40
  • 1
    OK. Be careful of straights using that method. If all you're doing is sorting the cards (presumably ace-high) after determining the hand type, then you run the risk of having A-2-3-4-5 beating things like 6-7-8-9-10, which wouldn't be correct, so you'll have to do some tweaking. – Crowman Jun 15 '13 at 14:50
  • More advice: determine if the hand is a flush *first*, it's a quick test and will simplify the other hand-type determinations. – Lee Daniel Crocker Jun 15 '13 at 18:53
3

Structure your evaluation function like this:

1) First, determine what type of hand it is (highest card, pair, two pair... royal flush). The hand type should be an enumeration ordered from worst to best.

2) Second, sort the cards in the hand - the cards that made up the hand type should go first (in particular, for a full house the three of a kind should go first before the two of the kind), then sort all remaining cards from best to worst.

3) Tuple the hand type and the sorted cards - this is the evaluation of how good the hand is.

Structure your comparison function like this:

1) First, compare the hand types. If one is higher, that hand is better.

2) Else, compare the first cards from the sorted hands. If one is higher, that hand is better.

3) Keep doing 2) on each card.

Now you can use your comparator to, for example, sort any number of hands into order from worst to best hand.

You could also create a score for each hand, and then just compare the integers - for example, worst (in the sense of least significant) card + second worst card*11 + third card*11^2 + fourth card*11^3 + best card*11^4 + hand type*11^5

Patashu
  • 21,443
  • 3
  • 45
  • 53
  • 1
    You should test your function against the complete set of phoer hand equivalence classes [here](http://www.suffecool.net/poker/7462.html). – Lee Daniel Crocker Jun 15 '13 at 18:51