import random import numpy import argparse import yaml TRIALS = 100000 HAND_SIZE = 8 SUITS = ['clubs', 'diamonds', 'hearts', 'spades'] def suit_gen(): for ii in range(4): yield SUITS[ii] def make_deck(): deck = [] for ii in range(13): for jj in suit_gen(): deck.append({'suit':jj, 'rank':ii + 2}) return deck def get_hand(deck): random.shuffle(deck) return sorted(deck[:HAND_SIZE], key=lambda card: card['rank']) def test_pair(hand): for ii in range(len(hand) - 1): for jj in range(ii + 1, len(hand)): if hand[ii]['rank'] == hand[jj]['rank']: ret_hand = hand[:] ret_hand.pop(jj) ret_hand.pop(ii) return True, ret_hand return False, hand def test_two_pair(hand): first_pair, test_hand = test_pair(hand) if first_pair: return test_pair(test_hand) else: return False, hand def test_three_of_a_kind(hand): for ii in range(len(hand) - 2): for jj in range(ii + 1, len(hand) - 1): for kk in range(jj + 1, len(hand)): if (hand[ii]['rank'] == hand[jj]['rank']) and (hand[ii]['rank'] == hand[kk]['rank']): ret_hand = hand[:] ret_hand.pop(kk) ret_hand.pop(jj) ret_hand.pop(ii) return True, ret_hand return False, hand def test_straight(hand): for ii in range(HAND_SIZE - 4): current_rank = hand[ii]['rank'] is_straight = True offset = 1 straight_length = 1 while straight_length < 5: if ii + offset >= len(hand): is_straight = False break elif (hand[ii + offset]['rank']) == (current_rank + straight_length): straight_length += 1 elif (hand[ii + offset]['rank']) > (current_rank + straight_length): is_straight = False break offset += 1 if is_straight: return True return False def test_flush(hand): suit_counts = {} for suit in SUITS: suit_counts[suit] = 0 for card in hand: suit_counts[card['suit']] = suit_counts[card['suit']] + 1 for suit in suit_counts: if suit_counts[suit] >= 5: return True return False def test_full_house(hand): three_of_a_kind, test_hand = test_three_of_a_kind(hand) if three_of_a_kind: return test_pair(test_hand)[0] else: return False def test_four_of_a_kind(hand): for ii in range(len(hand) - 3): for jj in range(ii + 1, len(hand) - 2): for kk in range(jj + 1, len(hand) - 1): for ll in range(kk + 1, len(hand)): if (hand[ii]['rank'] == hand[jj]['rank']) and (hand[ii]['rank'] == hand[kk]['rank']) and (hand[ii]['rank'] == hand[ll]['rank']): return True return False def test_straight_flush(hand): for ii in range(HAND_SIZE - 4): current_card = hand[ii] is_straight = True offset = 1 straight_length = 1 while straight_length < 5: if ii + offset >= len(hand): is_straight = False break elif (hand[ii + offset]['rank']) == (current_card['rank'] + straight_length) and (hand[ii + offset]['suit']) == (current_card['suit']): straight_length += 1 elif (hand[ii + offset]['rank']) > (current_card['rank'] + straight_length): is_straight = False break offset += 1 if is_straight: return True return False def main(): parser = argparse.ArgumentParser() parser.add_argument('-c', '--count', dest='trials', type=int, default=TRIALS, help='How many trials to run?') args = parser.parse_args() print("{0} trials.".format(args.trials)) deck = make_deck() #hand = [{'suit': 'clubs', 'rank': 3}, {'suit': 'clubs', 'rank': 3}, {'suit': 'clubs', 'rank': 5}, {'suit': 'clubs', 'rank': 5}, {'suit': 'clubs', 'rank': 7}, {'suit': 'clubs', 'rank': 7}, {'suit': 'clubs', 'rank': 11}] pair_count = 0.0 two_pair_count = 0.0 three_of_a_kind_count = 0.0 straight_count = 0.0 flush_count = 0.0 full_house_count = 0.0 four_of_a_kind_count = 0.0 straight_flush_count = 0.0 nothing_count = 0.0 for ii in range(args.trials): hand = get_hand(deck) if test_straight_flush(hand): straight_flush_count += 1.0 elif test_four_of_a_kind(hand): four_of_a_kind_count += 1.0 elif test_full_house(hand): full_house_count += 1.0 elif test_flush(hand): flush_count += 1.0 elif test_straight(hand): straight_count += 1.0 elif test_three_of_a_kind(hand)[0]: three_of_a_kind_count += 1.0 elif test_two_pair(hand)[0]: two_pair_count += 1.0 elif test_pair(hand)[0]: pair_count += 1.0 else: nothing_count += 1.0 print('Nothing %: {:.2%}'.format(nothing_count/args.trials)) print('Pair %: {:.2%}'.format(pair_count/args.trials)) print('Two Pair %: {:.2%}'.format(two_pair_count/args.trials)) print('Three of a Kind %: {:.2%}'.format(three_of_a_kind_count/args.trials)) print('Straight %: {:.2%}'.format(straight_count/args.trials)) print('Flush %: {:.2%}'.format(flush_count/args.trials)) print('Full House %: {:.2%}'.format(full_house_count/args.trials)) print('Four of a Kind %: {:.2%}'.format(four_of_a_kind_count/args.trials)) print('Straight Flush %: {:.2%}'.format(straight_flush_count/args.trials)) if __name__ == '__main__': main()