The simplest algorithm for poker hand evaluation

后端 未结 12 1030
独厮守ぢ
独厮守ぢ 2020-12-04 12:39

I am thinking about poker hand (5 cards) evaluation in Java. Now I am looking for simplicity and clarity rather than performance and efficiency. I probably can

12条回答
  •  借酒劲吻你
    2020-12-04 13:07

    Here's a modified version of dansalmo's program which works for holdem hands:

    def holdem(board, hands):
        scores = [(evaluate((board + ' ' + hand).split()), i) for i, hand in enumerate(hands)]
        best = max(scores)[0]
        return [x[1] for x in filter(lambda(x): x[0] == best, scores)]
    
    def evaluate(hand):
        ranks = '23456789TJQKA'
        if len(hand) > 5: return max([evaluate(hand[:i] + hand[i+1:]) for i in range(len(hand))])
        score, ranks = zip(*sorted((cnt, rank) for rank, cnt in {ranks.find(r): ''.join(hand).count(r) for r, _ in hand}.items())[::-1])
        if len(score) == 5: # if there are 5 different ranks it could be a straight or a flush (or both)
            if ranks[0:2] == (12, 3): ranks = (3, 2, 1, 0, -1) # adjust if 5 high straight
            score = ([1,(3,1,2)],[(3,1,3),(5,)])[len({suit for _, suit in hand}) == 1][ranks[0] - ranks[4] == 4] # high card, straight, flush, straight flush
        return score, ranks
    
    def test():
        print holdem('9H TC JC QS KC', [
            'JS JD', # 0
            'AD 9C', # 1 A-straight
            'JD 2C', # 2
            'AC 8D', # 3 A-straight
            'QH KH', # 4
            'TS 9C', # 5
            'AH 3H', # 6 A-straight
            '3D 2C', # 7
          # '8C 2C', # 8 flush
        ])
    
    test()
    

    holdem() returns a list of indices of the winning hand(s). In the test() example that's [1, 3, 6], since the three hands with aces split the pot, or [8] if the flush hand is uncommented.

提交回复
热议问题