Nickpick
Nickpick

Reputation: 6597

Sort algorithm: Comparing tuple to integer in python 3 with sort function

The below poker hand evaluator is generating a ranking of the different cards the players are holding. It works well in Python 2 but it doesn't work in python 3 because the sort function can no longer compare tuples to integers. How can I make it behave in python 3 the way it used to behave in python 2?

The sorting needs to decide which cards are the best:

(1, (11, 8, 7, 6, 2)) # high card 11 (rank5)
(1, (12, 11, 8, 7, 2)) # high card 12 (rank4)
((3, 2), (11, 12))  # full house (triple and pair) (rank1)
((2, 1, 1, 1), (12, 11, 7, 6)) # pair of 12 (rank3)
((3, 1, 1), (12, 6, 3)) # three of 12 (rank2)

If an integer is compared to a tuple, then the first item of the tuple should be relevant. The sort function in python 2 would correctly sort the above, but in python 3 I get an error message the integers cannot be compared to tuples.

How do I need to adapt the keyfunction?

def keyfunction(x):
    v= x[1]
    return v


def poker(hands):
    scores = [(i, score(hand.split())) for i, hand in enumerate(hands)]
    #print (scores)
    winner = sorted(scores , key=keyfunction)[-1][0]
    return hands[winner]

def score(hand):
    ranks = '23456789TJQKA'
    rcounts = {ranks.find(r): ''.join(hand).count(r) for r, _ in hand}.items()
    #print (rcounts)
    score, ranks = zip(*sorted((cnt, rank) for rank, cnt in rcounts)[::-1])
    if len(score) == 5:
        if ranks[0:2] == (12, 3): #adjust if 5 high straight
            ranks = (3, 2, 1, 0, -1)
        straight = ranks[0] - ranks[4] == 4
        flush = len({suit for _, suit in hand}) == 1
        '''no pair, straight, flush, or straight flush'''
        score = ([1, (3,1,1,1)], [(3,1,1,2), (5,)])[flush][straight]
    return score, ranks

poker(['8C TS KC 9H 4S','AC TS KC 9H 4S', 'AD AS KD KS KC', '9C AD KD AC 8C', 'AC 5H 8D AD AS'])

Upvotes: 0

Views: 145

Answers (1)

Hendrik Makait
Hendrik Makait

Reputation: 1052

You could simply transform the integer indicating a high card when assigning score into a one-element tuple.

...
score = ([(1, ), (3,1,1,1)], [(3,1,1,2), (5,)])[flush][straight]
...

Upvotes: 2

Related Questions