import requests url = 'https://projecteuler.net/project/resources/p054_poker.txt' text = requests.get(url).text hands = text.splitlines() faces = { 'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14 } tests = [ '5H 5C 6S 7S KD 2C 3S 8S 8D TD', '2C 3S 8S 8D TD 2C 5C 7D 8S QH', '2D 9C AS AH AC 3D 6D 7D TD QD', '4D 6S 9H QH QC 3D 6D 7H QD QS', '2H 2D 4C 4D 4S 3C 3D 3S 9S 9D' ] def is_straight(cards): ranks = [x[0] for x in cards] for idx, rank in enumerate(ranks): try: ranks[idx] = int(rank) except ValueError: ranks[idx] = faces[rank] if max(ranks) - min(ranks) == 4 and len(set(ranks)) == 5: return True return False def is_flush(cards): suits = [x[1] for x in cards] return all(x == suits[0] for x in suits) def get_ranks(cards): ranks = [x[0] for x in cards] for idx, rank in enumerate(ranks): try: ranks[idx] = int(rank) except ValueError: ranks[idx] = faces[rank] return ranks def resolve_tie(hand_one, hand_two): value = get_value(hand_one) hand_one_ranks = get_ranks(hand_one) hand_two_ranks = get_ranks(hand_two) if is_straight(hand_one): if max(hand_one_ranks) > max(hand_two_ranks): return 0 else: return 1 if value in [2, 3, 6, 7, 8]: most_common_one = max(set(hand_one_ranks), key=hand_one_ranks.count) most_common_two = max(set(hand_two_ranks), key=hand_two_ranks.count) if most_common_one > most_common_two: return 0 elif most_common_two > most_common_one: return 1 else: if value not in [6, 8]: raise Exception('second level tie needed') for idx, card in enumerate(sorted(hand_one_ranks)[::-1]): if card > sorted(hand_two_ranks)[-1-idx]: return 0 if card < sorted(hand_two_ranks)[-1-idx]: return 1 def get_value(cards): assert len(cards) == 5 ranks = [x[0] for x in cards] for idx, rank in enumerate(ranks): try: ranks[idx] = int(rank) except ValueError: ranks[idx] = faces[rank] flush = is_flush(cards) straight = is_straight(cards) groups = {} for card in ranks: try: groups[card] += 1 except KeyError: groups[card] = 1 print(groups) group_most = max(groups.values()) if flush and sorted(ranks) == [10, 11, 12, 13, 14]: # royal flush return 0 elif flush and straight: # straight flush return 1 elif group_most == 4: # four of a kind return 2 elif len(groups) == 2 and group_most == 3: # full house return 3 elif flush: # flush return 4 elif straight: # straight return 5 elif group_most == 3: # three of a kind return 6 elif group_most == 2 and len(groups) == 3: # two pair return 7 elif group_most == 2 and len(groups) == 4: # pair return 8 else: # high card return 9 if __name__ == '__main__': results = {'player_one': 0, 'player_two': 0} for idx, hand in enumerate(hands): print(idx) hand = hand.split(' ') player_one = hand[:5] player_two = hand[5:] player_one_value = get_value(player_one) player_two_value = get_value(player_two) print('player_one', player_one, player_one_value, is_flush(player_one), is_straight(player_one)) print('player_two', player_two, player_two_value, is_flush(player_two), is_straight(player_two)) if player_one_value == player_two_value: if resolve_tie(player_one, player_two) == 0: print('player_one_wins') results['player_one'] += 1 elif resolve_tie(player_one, player_two) == 1: print('player_two wins') results['player_two'] += 1 elif player_one_value < player_two_value: print('player_one wins') results['player_one'] += 1 else: print('player_two wins') results['player_two'] += 1 print(results)