-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcards.py
executable file
·351 lines (283 loc) · 10.7 KB
/
cards.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
import itertools
import random
class Card:
def __init__(self, rank, suit):
self.suit = suit
self.rank = rank
def __str__(self):
if self.getRank() > 10:
if self.getRank() == 11:
return str('J' + self.getSuit())
if self.getRank() == 12:
return str('D' + self.getSuit())
if self.getRank() == 13:
return str('K' + self.getSuit())
if self.getRank() == 14:
return str('A' + self.getSuit())
else:
return str(str(self.getRank()) + self.getSuit())
def __repr__(self):
return self.__str__()
def getSuit(self):
return self.suit
def getRank(self):
return self.rank
def __lt__(self, other):
if other.getRank() > self.getRank():
return True
else:
return False
def __eq__(self, other):
if self.getRank() == other.getRank():
return True
else:
return False
class CardDeck:
def __init__(self, suits=['T', 'K', 'P', 'C'], ranks=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]):
self.suits = suits
self.ranks = ranks
self.cards = []
for suit in self.suits:
for rank in self.ranks:
self.cards.append(Card(rank, suit))
self.shuffled = False
def shuffle(self):
for a in range(99):
random.shuffle(self.cards)
def deal(self):
return self.cards.pop(0)
def __str__(self):
k = []
for karta in self.cards:
k.append(str(karta))
return str(k)
def getDeck(self):
return self.cards
class FinalHand():
def __init__(self, typek, cards):
# types: pair,two, three, flush, straight, four, full, straightflush, royalflush
# cards: it must be a touple
self.type = typek
self.cards = ()
for instance in cards:
self.cards += (instance,)
def getType(self):
return self.type
def getCardsAsString(self):
ku = ""
for a in self.cards:
ku += (" " + str(a))
return ku
def getCards(self):
return self.cards
def __str__(self):
return '%s : %s' % (self.getType(), self.getCardsAsString())
def __repr__(self):
return self.__str__()
def __lt__(self, other):
wert = {'highcard': 0, 'pair': 1, 'two': 2, 'three': 3, 'straight': 4, 'flush': 5, 'full': 6, 'four': 7,
'straightflush': 8, 'royalflush': 9}
if wert[self.getType()] < wert[other.getType()]:
return True
elif self.getType() == other.getType():
leng = len(self.getCards())
counter = -1
while other.getCards()[counter].getRank() == self.getCards()[counter].getRank() and counter * -1 != leng:
counter -= 1
if counter * -1 == leng:
return False
else:
return other.getCards()[counter].getRank() > self.getCards()[counter].getRank()
else:
return False
def __eq__(self, other):
if type(other) == type(self):
if self.getType() == other.getType():
leng = len(self.getCards())
counter = -1
while other.getCards()[counter].getRank() == self.getCards()[
counter].getRank() and counter * -1 != leng:
counter -= 1
if counter * -1 == leng:
return True
else:
return False
else:
return False
else:
return other == self
def __hash__(self):
return hash(id(self))
def list_to_tuple(listka):
c = ()
for a in listka:
c += (a,)
return c
def flatten_tuple(tupl):
k = []
for d in tupl:
for c in d:
k.append(c)
k.sort()
return list_to_tuple(k)
def find_final_hands(lysta):
# Input: set - list of cards to evaluate
# Output: list of hand classed objects
lysta.sort()
suits = ['T', 'K', 'P', 'C']
# makes two dictionaries; bysuit - cards sorted by suit, byrank - cards sorted by rank
# bysuit/byrank[a]=(number,(touple of cards))
# example: bysuit['T']=(4,(2T,8T,9T,KT))
bysuit = {}
byrank = {}
for kind in suits:
bysuit[kind] = (0, [])
for a in range(len(lysta)):
karta = lysta[a]
su = karta.getSuit()
ra = karta.getRank()
# =======================================================================
# #bysuit
# =======================================================================
asuit = bysuit[su]
asuitlist = asuit[1]
asuitlist.append(karta)
bysuit[su] = (asuit[0] + 1, asuitlist)
# =======================================================================
# #byrank
# =======================================================================
if ra in byrank.keys():
arank = byrank[ra]
aranklist = arank[1]
aranklist.append(karta)
byrank[ra] = (arank[0] + 1, aranklist)
else:
byrank[ra] = (1, [karta])
# sets up a collection of hands as a list:
hands = []
# ===========================================================================
# #highcard:
# ===========================================================================
hands.append(FinalHand('highcard', list_to_tuple(lysta)))
# ===========================================================================
# #pairs,three of a kind, four of a kind
# ===========================================================================
# Set up a counters for pairs/ three
pairs = []
threes = []
for ele in byrank.keys():
if byrank[ele][0] >= 2:
space = list(itertools.combinations(byrank[ele][1], 2))
for g in space:
hands.append(FinalHand('pair', g))
pairs.append(g)
if byrank[ele][0] >= 3:
space = list(itertools.combinations(byrank[ele][1], 3))
for h in space:
hands.append(FinalHand('three', h))
threes.append(h)
if byrank[ele][0] == 4:
hands.append(FinalHand('four', byrank[ele][1]))
# ===========================================================================
# #twopair
# ===========================================================================
if len(pairs) >= 2:
space = list(itertools.combinations(pairs, 2))
for v in space:
if v[0][0].getRank() != v[1][0].getRank():
hands.append(FinalHand('two', flatten_tuple(v)))
# ===========================================================================
# # full
# ===========================================================================
if len(pairs) >= 1 and len(threes) >= 1:
space = list(itertools.product(pairs, threes))
for v in space:
if v[0][0].getRank() != v[1][0].getRank():
hands.append(FinalHand('full', flatten_tuple(v)))
# ===========================================================================
# #flush
# ===========================================================================
for a in bysuit.keys():
bysuit[a][1].sort()
numerek = bysuit[a][0]
if numerek >= 5:
space = list(itertools.combinations(bysuit[a][1], 5))
for helo in space:
hands.append(FinalHand('flush', helo))
# ===========================================================================
# #straight/straightflush/royalflush
# ===========================================================================
if len(byrank.keys()) >= 5:
mainstraightspace = []
for rank in range(2, 10):
straight = True
lyst = []
for helper in range(6):
if helper + rank not in byrank.keys():
straight = False
else:
lyst.append(byrank[helper + rank][1])
if straight == True:
straightspace = list(itertools.product(lyst[0], lyst[1], lyst[2], lyst[3], lyst[4]))
for uklad in straightspace:
mainstraightspace.append(uklad)
# =======================================================================
# #Kind of straight checker:
# =======================================================================
for stra in mainstraightspace:
flush = True
last = None
for strcard in stra:
if strcard.getSuit() == last or last == None:
last = strcard.getSuit()
else:
flush = False
if flush == True:
if stra[-1].getRank() == 14:
hands.append(FinalHand('royalflush', stra))
else:
hands.append(FinalHand('straightflush', stra))
else:
hands.append(FinalHand('straight', stra))
if len(hands) != 0:
hands.sort()
return hands
def listUnion(a, b):
""" return the union of two lists """
d = []
for c in b:
d.append(c)
for g in a:
d.append(g)
return d
def checkbyrank(known, rank):
# returns number of cards that are still unknown and could fullfill the criterium
# known has to be a list of known cards
counter = 4
for kart in known:
if kart.getRank() == rank:
counter -= 1
return counter
def checkbysuit(known, suit):
# returns number of cards that are still unknown and could fullfill the criterium
# known has to be a list of known cards
counter = 13
for kart in known:
if kart.getSuit() == suit:
counter -= 1
return counter
def computeprobsingle(needed, aviable, leftondeck):
# needed - number of needed cards as an int
# aviable - number of aviable cards still in deck
# RETURNS:
# probability of drawing x needed of the same kind from deck
if needed > aviable:
return 0
else:
result = 1
while needed > 0:
result = result * aviable * 1.0 / leftondeck
aviable -= 1
leftondeck -= 1
needed -= 1
return result