נצרף גם את שלי 
PICTURES = ('T', 'J', 'Q', 'K', 'A')
SUIT_TYPES = ('C', 'D', 'H', 'S')
NUMBER = 0
SUIT = 1
NUMBER_OF_CARDS = 5
def parse_number(number):
if number in PICTURES:
parsed_number = PICTURES.index(number) + 10
else:
parsed_number = int(number)
return parsed_number
def parse_card(card):
parsed_number = parse_number(card[NUMBER])
return parsed_number, card[SUIT]
def parse_hand(cards):
i = 0
new_cards = []
while i < len(cards):
parsed_card = parse_card(cards[i])
new_cards.append(parsed_card)
i += 1
return new_cards
def count_card_numbers(hand):
times_each_number_appeared = [0] * 15
i = 0
while i < len(hand):
number = hand[i][NUMBER]
times_each_number_appeared[number] += 1
i += 1
times_each_number_appeared[1] = times_each_number_appeared[14] # Ace
return times_each_number_appeared
def count_suits(hand):
suits_counter = [0] * 4
i = 0
while i < len(hand):
suit = hand[i][SUIT]
suit_index = SUIT_TYPES.index(suit)
suits_counter[suit_index] += 1
i += 1
return suits_counter
def get_only_numbers(hand):
i = 0
numbers = []
while i < len(hand):
numbers.append(hand[i][NUMBER])
i += 1
return numbers
def get_hand_as_kickers(hand):
numbers = get_only_numbers(hand)
numbers.sort()
return numbers[::-1]
def get_highest_x_of_kind(hand, x):
times_each_number_appears = count_card_numbers(hand)
# The highest cards are in the end, so we flip the list
if x in times_each_number_appears:
descending_number_count = times_each_number_appears[::-1]
highest_x_of_kind = descending_number_count.index(x)
real_card_value = 15 - highest_x_of_kind - 1
return real_card_value
return False
def find_flush_color(hand, flush_length):
suit = 0 # 0 = C, 1 = D, 2 = H, 3 = S
suits_counter = count_suits(hand)
while suit < len(suits_counter) and suits_counter[suit] < flush_length:
suit += 1
if suit >= len(suits_counter): # We've gone through all the options
return False
return suit
def filter_by_suit(hand, suit):
if str(suit).isdigit():
suit = SUIT_TYPES[suit]
i = 0
filtered = []
while i < len(hand):
if hand[i][SUIT] == suit:
filtered.append(hand[i])
i += 1
return filtered
def get_highest_of_suit(hand, suit, k):
filtered = filter_by_suit(hand, suit)
filtered.sort()
return filtered[-k:]
def get_flush(hand, flush_length):
flush_color = find_flush_color(hand, flush_length)
if flush_color == False:
return False
flush = get_highest_of_suit(hand, flush_color, flush_length)
if len(flush) != flush_length:
return False
return flush
def get_straight(hand, straight_length):
card_numbers = count_card_numbers(hand)
i = len(card_numbers) - 1
length_so_far = 1
while 0 < i:
if length_so_far == straight_length:
return i + length_so_far - 1
if card_numbers[i] > 0 and card_numbers[i - 1] > 0:
length_so_far += 1
else:
length_so_far = 1
i -= 1
return False
def get_two_pairs(hand):
pair = get_highest_x_of_kind(hand, 2)
if not pair:
return False
hand2 = filter_out_number(hand, pair)
another_pair = get_highest_x_of_kind(hand2, 2)
if not another_pair:
return False
kicker = filter_out_number(hand2, another_pair)
return pair, another_pair, kicker
def get_kickers(hand, numbers_to_filter):
i = 0
hand2 = hand.copy()
while i < len(numbers_to_filter):
hand2 = filter_out_number(hand2, numbers_to_filter[i])
i += 1
hand_numbers = get_only_numbers(hand2)
hand_numbers.sort()
return hand_numbers[::-1] # Highest first
def filter_out_number(hand, number):
i = 0
new_hand = []
while i < len(hand):
if hand[i][NUMBER] != number:
new_hand.append(hand[i])
i += 1
return new_hand
def get_hand_strength(hand):
flush = get_flush(hand, NUMBER_OF_CARDS)
straight = get_straight(hand, NUMBER_OF_CARDS)
if flush and straight:
return 8, straight
four_of_a_kind = get_highest_x_of_kind(hand, 4)
if four_of_a_kind:
kicker = get_kickers(hand, [four_of_a_kind])
return 7, four_of_a_kind, kicker
three_of_a_kind = get_highest_x_of_kind(hand, 3)
pair = get_highest_x_of_kind(hand, 2)
if three_of_a_kind and pair:
return 6, three_of_a_kind, pair
if flush:
return 5, get_hand_as_kickers(hand)
if straight:
return 4, straight
if three_of_a_kind:
return 3, three_of_a_kind, get_kickers(hand, [three_of_a_kind])
two_pairs = get_two_pairs(hand)
if two_pairs:
kicker = get_kickers(hand, two_pairs)
return 2, two_pairs[0], two_pairs[1], kicker
if pair:
kicker = get_kickers(hand, [pair])
return 1, pair
return 0, get_hand_as_kickers(hand)
def get_winning_hand(hand1, hand2):
strength1 = get_hand_strength(hand1)
strength2 = get_hand_strength(hand2)
if strength1 > strength2:
return 0
elif strength1 < strength2:
return 1
return 2
def add_all_uniques(l, items):
i = 0
while i < len(items):
if items[i] not in l:
l.append(items[i])
i += 1
return items
def create_all_hands_combinations(hand, length):
if len(hand) == length:
return [hand]
combinations = []
i = 0
while i < len(hand):
rest_of_hand = hand[:i] + hand[i+1:]
created = create_all_hands_combinations(rest_of_hand, length)
add_all_uniques(combinations, created)
i += 1
return combinations
def get_best_of_hands(hands):
if not hands:
return []
best_hand = hands[0]
max_i = 0
i = 1
while i < len(hands):
current_hand = hands[i]
winning_hand = get_winning_hand(best_hand, current_hand)
if winning_hand % 2 == 1:
best_hand = current_hand
max_i = i
i += 1
return (best_hand, max_i)
def create_best_hand(larger_hand, wanted_size):
combinations = create_all_hands_combinations(larger_hand, wanted_size)
i = 0
parsed_combinations = []
while i < len(combinations):
parsed_combinations.append(parse_hand(combinations[i]))
i += 1
return get_best_of_hands(parsed_combinations)[0]
def get_best_player(hands, public):
i = 0
new_hands = []
while i < len(hands):
actual_hand = create_best_hand(hands[i] + public, 5)
print(actual_hand)
new_hands.append(actual_hand)
i += 1
return get_best_of_hands(new_hands)[1]
def test_strength(hand, expected_strength):
parsed_hand = parse_hand(hand)
strength = get_hand_strength(parsed_hand)
assert strength == expected_strength, f"{hand}:\t{strength} != {expected_strength}"
test_strength(['TH', 'AH', 'QH', 'KH', '3S'], (0, [14, 13, 12, 10, 3]))
test_strength(['TH', 'TH', 'QH', 'KH', '3S'], (1, 10))
test_strength(['2H', 'QH', '2H', 'KH', '3S'], (1, 2))
test_strength(['2H', 'QH', '2S', 'QS', '3S'], (2, 12, 2, [3]))
test_strength(['QH', 'QC', '2H', 'QS', '3S'], (3, 12, [3, 2]))
test_strength(['AH', 'KS', 'QH', 'JH', 'TS'], (4, 14))
test_strength(['9H', 'KS', 'QH', 'JH', 'TS'], (4, 13))
test_strength(['9H', '5H', '3H', 'JH', 'TH'], (5, [11, 10, 9, 5, 3]))
test_strength(['9H', '9S', '9C', 'JH', 'JS'], (6, 9, 11))
test_strength(['9H', '9S', 'JC', 'JH', 'JS'], (6, 11, 9))
test_strength(['9H', 'JD', 'JC', 'JH', 'JS'], (7, 11, [9]))
test_strength(['AH', 'KH', 'QH', 'JH', 'TH'], (8, 14))
test_strength(['9H', 'KH', 'QH', 'JH', 'TH'], (8, 13))
print(create_best_hand(['2S', '9H', 'KH', '5S', 'QH', 'JH', 'TH'], 5))
print(get_best_player([['2S, 9H'], ['9H', 'KH'], ['5H', '6H'], ['7H', '4H']], ['QH', 'JH', 'TH', '8H']))