-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_json.py
126 lines (99 loc) · 3.75 KB
/
build_json.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import itertools
import time
import json
import cardsutils
import math
# Function dict_hand_rank ranks every board and returns a tuple (board) (value)
def hand_rank_dict(hand, use_prime_key=False):
suits = []
ranks_alphabetical = []
ranks_numerical = []
ranks_histogram = []
ranks = cardsutils.ranks
is_flush = False
is_straight = False
handrank_value = 0
straight_height = -1
for card in hand:
suits.append(card[1])
ranks_alphabetical.append(card[0])
# create ranks_histogram where from A 2 ... J Q K A every card has the corresponding number of occurencies, A double counted
ranks_histogram.append(str(ranks_alphabetical.count("A")))
for rank in ranks:
ranks_histogram.append(str(ranks_alphabetical.count(rank)))
joined_histogram = "".join(ranks_histogram)
# create ranks numerical instead of T, J, Q, K
for card in hand:
ranks_numerical.append(cardsutils.ranks_map[card[0]])
# create kickers
kickers = sorted(
[x for x in ranks_numerical if ranks_numerical.count(x) < 2], reverse=True
)
# check if a hand is a straight
if "11111" in joined_histogram:
is_straight = True
straight_height = joined_histogram.find("11111") + 5
handrank_value = (4,) + (straight_height,)
# check if a hand is a flush
if all(x == suits[0] for x in suits):
is_flush = True
handrank_value = (5,) + tuple(kickers)
# check if a hand is a straight and a flush
if is_flush & is_straight:
handrank_value = (8,) + (straight_height,)
# check if a hand is four of a kind
if "4" in joined_histogram:
handrank_value = (7,) + ((joined_histogram[1:].find("4") + 2),) + tuple(kickers)
# check if a hand is a full house
if ("3" in joined_histogram) & ("2" in joined_histogram):
handrank_value = (
(6,)
+ ((joined_histogram[1:].find("3") + 2),)
+ ((joined_histogram[1:].find("2") + 2),)
+ tuple(kickers)
)
# check if a hand is three of a kind
if ("3" in joined_histogram) & (len(kickers) == 2):
handrank_value = (3,) + ((joined_histogram[1:].find("3") + 2),) + tuple(kickers)
# check if a hand is two pairs
if ("2" in joined_histogram) & (len(kickers) == 1):
lowerpair = joined_histogram[1:].find("2") + 2
higherpair = joined_histogram[lowerpair:].find("2") + 1 + lowerpair
handrank_value = (2,) + (higherpair, lowerpair) + tuple(kickers)
# check if a hand is one pair
if ("2" in joined_histogram) & (len(kickers) == 3):
lowerpair = joined_histogram[1:].find("2") + 2
handrank_value = (1,) + (lowerpair,) + tuple(kickers)
# evaluate high card hand
if (
(len(ranks_numerical) == len(set(ranks_numerical)))
& (is_straight == False)
& (is_flush == False)
):
handrank_value = (0,) + tuple(kickers)
if use_prime_key:
return {
math.prod(
[cardsutils.deck_dict_with_primes[x] for x in hand]
): rank_integer(handrank_value)
}
else:
return {"".join(sorted(hand)): rank_integer(handrank_value)}
def build_hands_dict(deck, path, use_prime_key=False):
ranked_hands_dict = {}
t0 = time.time()
for five_card_hand in itertools.combinations(deck, 5):
ranked_hands_dict.update(hand_rank_dict(five_card_hand, use_prime_key))
t1 = time.time()
total = t1 - t0
print(total)
with open(path, "w") as f:
json.dump(ranked_hands_dict, f)
def rank_integer(rank_tuple):
m = 100 ** 5
score = 0
for x in rank_tuple:
score += x * m
m /= 100
return int(score)
build_hands_dict(cardsutils.deck_as_set, r"hands_prime.json", use_prime_key=True)