160 lines
4.3 KiB
Python
160 lines
4.3 KiB
Python
|
|
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)
|
|
|