From b529694923fda3ff1d3eb4f926602e971223f7bf Mon Sep 17 00:00:00 2001 From: Fran314 Date: Wed, 4 Dec 2024 03:35:58 +0100 Subject: [PATCH] initial commit --- README.md | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 313 insertions(+) create mode 100644 README.md create mode 100755 main.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..8d9e87d --- /dev/null +++ b/README.md @@ -0,0 +1,152 @@ +Results + +``` +========================= +cards on table: 5 +------------------------- + high card 34.14% + one pair 4.16% + three of a kind 0.16% + two pair 0.06% + flush 0.04% + straight 0.04% + full house 0.01% + four of a kind 0.00% + straight flush 0.00% +========================= + + +========================= +cards on table: 10 +------------------------- + high card 58.63% + one pair 16.27% + flush 5.56% + straight 4.18% + two pair 1.97% + three of a kind 1.95% + full house 0.33% + four of a kind 0.08% + straight flush 0.04% +========================= + + +========================= +cards on table: 15 +------------------------- + high card 75.52% + one pair 32.62% + flush 29.23% + straight 20.51% + two pair 9.33% + three of a kind 6.74% + full house 2.11% + four of a kind 0.50% + straight flush 0.43% +========================= + + +========================= +cards on table: 20 +------------------------- + high card 86.81% + flush 62.61% + one pair 50.10% + straight 46.66% + two pair 23.60% + three of a kind 15.17% + full house 7.34% + straight flush 2.32% + four of a kind 1.76% +========================= + + +========================= +cards on table: 25 +------------------------- + high card 93.46% + flush 86.91% + straight 70.18% + one pair 66.46% + two pair 42.93% + three of a kind 27.68% + full house 18.05% + straight flush 8.08% + four of a kind 4.71% +========================= + + +========================= +cards on table: 30 +------------------------- + flush 97.28% + high card 97.18% + straight 86.41% + one pair 80.28% + two pair 63.73% + three of a kind 43.11% + full house 34.30% + straight flush 20.66% + four of a kind 10.20% +========================= + + +========================= +cards on table: 35 +------------------------- + flush 99.81% + high card 99.17% + straight 95.85% + one pair 90.40% + two pair 81.44% + three of a kind 60.41% + full house 54.46% + straight flush 42.98% + four of a kind 19.26% +========================= + + +========================= +cards on table: 40 +------------------------- + flush 99.99% + high card 99.82% + straight 99.10% + one pair 96.67% + two pair 93.39% + three of a kind 77.70% + full house 75.08% + straight flush 72.44% + four of a kind 33.51% +========================= + + +========================= +cards on table: 45 +------------------------- + flush 100.00% + high card 99.99% + straight 99.95% + one pair 99.40% + two pair 98.79% + straight flush 95.18% + three of a kind 91.70% + full house 91.16% + four of a kind 55.07% +========================= + + +========================= +cards on table: 50 +------------------------- + two pair 100.00% + high card 100.00% + one pair 100.00% + straight 100.00% + straight flush 100.00% + flush 100.00% + three of a kind 99.55% + full house 99.55% + four of a kind 85.07% +========================= +``` diff --git a/main.py b/main.py new file mode 100755 index 0000000..79948ba --- /dev/null +++ b/main.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python + +from itertools import combinations, product +from random import sample + +import matplotlib.pyplot as plt +import numpy as np + +SAMPLE_SIZE = 10000 + +RANKS = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] +LOOPED_RANKS = [RANKS[-1]] + RANKS +SUITS = ["♥", "♦", "♣", "♠"] +DECK = list(product(RANKS, SUITS)) + +def count_rank(table, rank): + return len(list(filter(lambda card: card[0] == rank, table))) +def count_suit(table, suit): + return len(list(filter(lambda card: card[1] == suit, table))) + +def find_high_card(table): + output = {} + for rank in RANKS: + output[rank] = count_rank(table, rank) >= 1 + return output +def find_one_pair(table): + output = {} + for rank in RANKS: + output[rank] = count_rank(table, rank) >= 2 + return output +def find_two_pair(table): + output = {} + for (rank1, rank2) in combinations(RANKS, 2): + output[rank1 + '+' + rank2] = count_rank(table, rank1) >= 2 and count_rank(table, rank2) >= 2 + return output +def find_three_of_a_kind(table): + output = {} + for rank in RANKS: + output[rank] = count_rank(table, rank) >= 3 + return output +def find_straight(table): + output = {} + for i in range(4, len(LOOPED_RANKS)): + output[LOOPED_RANKS[i]] = (count_rank(table, LOOPED_RANKS[i-4]) >= 1 and + count_rank(table, LOOPED_RANKS[i-3]) >= 1 and + count_rank(table, LOOPED_RANKS[i-2]) >= 1 and + count_rank(table, LOOPED_RANKS[i-1]) >= 1 and + count_rank(table, LOOPED_RANKS[i]) >= 1) + return output +def find_flush(table): + output = {} + for suit in SUITS: + output[suit] = count_suit(table, suit) >= 5 + return output +def find_full_house(table): + output = {} + for (rank1, rank2) in product(RANKS, RANKS): + output[rank1 + ' over ' + rank2] = count_rank(table, rank1) >= 3 and count_rank(table, rank2) >= 2 + return output +def find_four_of_a_kind(table): + output = {} + for rank in RANKS: + output[rank] = count_rank(table, rank) >= 4 + return output +def find_straight_flush(table): + output = {} + for i in range(4, len(LOOPED_RANKS)): + found = False + for s in SUITS: + if ((LOOPED_RANKS[i-4], s) in table and + (LOOPED_RANKS[i-3], s) in table and + (LOOPED_RANKS[i-2], s) in table and + (LOOPED_RANKS[i-1], s) in table and + (LOOPED_RANKS[i], s) in table): + found = True + + output[LOOPED_RANKS[i]] = found + return output + +def find_hands(table): + return { + "high card": find_high_card(table), + "one pair": find_one_pair(table), + "two pair": find_two_pair(table), + "three of a kind": find_three_of_a_kind(table), + "straight": find_straight(table), + "flush": find_flush(table), + "full house": find_full_house(table), + "four of a kind": find_four_of_a_kind(table), + "straight flush": find_straight_flush(table), + } + + +def find_hand_averages(result): + output = {} + for hand in result: + output[hand] = 0 + for hand_type in result[hand]: + output[hand] += result[hand][hand_type] / len(result[hand]) + return output +def find_probabilities(size): + results = [find_hands(sample(DECK, size)) for _ in range(SAMPLE_SIZE)] + output = {} + for hand in results[0]: + output[hand] = {} + for hand_type in results[0][hand]: + output[hand][hand_type] = 0 + for i in range(SAMPLE_SIZE): + if results[i][hand][hand_type]: + output[hand][hand_type] += 1/SAMPLE_SIZE + return find_hand_averages(output) + +groups = tuple(range(5, 52, 5)) +global_results = { + "high card": (), + "one pair": (), + "two pair": (), + "three of a kind": (), + "straight": (), + "flush": (), + "full house": (), + "four of a kind": (), + "straight flush": (), +} +for size in groups: + print("=========================") + print("cards on table:", str(size).rjust(8)) + print("-------------------------") + results = find_probabilities(size) + for hand in global_results: + global_results[hand] += (results[hand],) + results = sorted(results.items(), key=lambda hand: -hand[1]) + for (hand, p) in results: + str_p = f"{p:.2%}" + print(" " + hand.ljust(15) + str_p.rjust(8)) + print("=========================") + print("") + print("") + +x = np.arange(len(groups)) # the label locations +width = 0.08 # the width of the bars +multiplier = 0 + +fig, ax = plt.subplots(layout='constrained') + +for attribute, measurement in global_results.items(): + offset = width * multiplier + rects = ax.bar(x + offset, measurement, width, label=attribute) + # ax.bar_label(rects, padding=3) + multiplier += 1 + +# Add some text for labels, title and custom x-axis tick labels, etc. +ax.set_ylabel('Probabilità') +ax.set_title('Probabilità mani poker polacco in funzione del numero di carte in gioco') +ax.set_xticks(x + width*4, groups) +ax.legend(loc='upper left', ncols=3) +ax.set_ylim(0, 1.05) + +plt.show() + +