def get_straights(self): straights = [] ordered_values = Card.all_values() for i in range(len(ordered_values)-4): for j in range(5): if len(self.value_groups[ ordered_values[i+j] ]) == 0: break else: # if the `break` statement is never called, then the below will execute for straight in itertools.product(*[self.value_groups[ ordered_values[i+j] ] for j in range(5)]): straights.append( tuple(sorted(straight)) ) # this is because the 'A' is at the beginning of `Card.all_values()` # so we haven't accounted for the [T, J, Q, K, A] stright for value in ['T', 'J', 'Q', 'K', 'A']: if len(self.value_groups[value]) == 0: break else: # if the `break` statement is never called, then the below will execute for straight in itertools.product(*[self.value_groups[value] for value in ['T', 'J', 'Q', 'K', 'A']]): straights.append( tuple(sorted(straight)) ) return straights
def get_best_hand(self): # useful data structures self.value_groups = { value : [] for value in Card.all_values() } self.suit_groups = { suit : [] for suit in Card.all_suits() } for card in self.cards: self.value_groups[card.value].append(card) self.suit_groups[card.suit].append(card) # get each category flushes = self.get_flushes() straights = self.get_straights() quads = self.get_quads() sets = self.get_sets() pairs = self.get_pairs() # sort them to make things easier later flushes = list(sorted(flushes, key=lambda cards: cards[-1])) straights = list(sorted(straights, key=lambda cards: cards[-1])) quads = list(sorted(quads, key=lambda cards: cards[-1])) sets = list(sorted(sets, key=lambda cards: cards[-1])) # checking for royal-flushes / straight-flushes for flush in flushes: for straight in straights: if flush == straight: self.best = flush if flush[-1].value == 'A': self.description = "Royal Flush" else: self.description = f"Straight Flush: {flush[-1].value} high" return self.best # checking for four of a kinds if len(quads) > 0: self.best = tuple( list(quads[-1]) + self.cards[-1:] ) self.description = f"Four of a Kind: {self.best[-1].value}s" # checking for full houses if len(sets) > 0: highest_set = sets[-1] highest_pair = None if len(sets) > 1: highest_pair = (sets[-2][0], sets[-2][1]) if len(pairs) > 0: if highest_pair is None or pairs[-1][0].value > highest_pair[0].value: highest_pair = pairs[-1] if not highest_pair is None: self.best = tuple( list(highest_set) + list(highest_pair) ) self.description = f"Full House: {self.best[0].value}s full of {self.best[-1].value}s" return self.best # checking for flushes if len(flushes) > 0: self.best = flushes[-1] self.description = f"Flush: {self.best[-1].value} high" return self.best # checking for straights if len(straights) > 0: self.best = straights[-1] self.description = f"Straight: {self.best[-1].value} high" return self.best # checking for three of a kind if len(sets) > 0: self.best = tuple( list(sets[-1]) + self.cards[-2:] ) self.description = f"Three of a Kind: {self.best[0].value}s" return self.best # checking for two pair if len(pairs) > 1: self.best = tuple( list(pairs[-1]) + list(pairs[-2]) + self.cards[-1:] ) self.description = f"Two Pair: {self.best[0].value}s and {self.best[2].value}s" return self.best # checking for one pair if len(pairs) > 0: self.best = tuple( list(pairs[-1]) + self.cards[-3:] ) self.description = f"Pair: {self.best[0].value}s" return self.best # return highest cards self.best = tuple(reversed(sorted( self.cards[-5:] ))) self.description = f"High Card: {self.best[0].value}" return self.best