I am attempting to write a game of blackjack using classes in Python. Any advice on keeping it DRY? I seem to be creating too many lists in lists. Should I name the keys in the dictionary or just use integers?
import random import itertools as it number_players = 2 #input('Enter Number of Players here: ') number_cards = 2 #input('Enter Number of Cards here: ') # create the deck of cards deck = list(it.product("♠♣♥♦", [str(x) for x in range(2, 11)] + list("JQKA"))) random.shuffle(deck) # print(len(deck)) # print(deck) # init the memo memo = set() def set_shuffle(n): for i in range(n): k = random.choice(deck) if k not in memo: memo.add(k) else: set_shuffle(1) return memo #sorted(memo) i = set_shuffle(52) def deal(deck, number_players, number_cards): """ Deals n amount of cards to n amount of players. """ player_dict = {'Player' + str(k + 1): [i.pop() for x in range(number_cards)] for k in range(number_players)} dealer_hand = [i.pop() for x in range(number_cards)] player_dict['Dealer'] = dealer_hand return player_dict players = deal(deck, number_players, number_cards) def print_current_cards(player_dict): """ pretty prints the current hands """ for k, v in player_dict.items(): print('{} hand:'.format(k)) for u in v: print(u[1], u[0]) print('\n') print_current_cards(players) class Player: """Takes in a players cards for processing""" def __init__(self, cards, player): self.cards = cards self.player = player def pic_to_int(self, card): """takes in a card and converts it to an integer of 10 for JQK or 10 and 11 for A """ card_list = ['J', 'Q', 'K', '10'] if card in card_list: return 10 elif card == 'A': return 11 if card not in card_list and card != 'A': return int(card) def current_score(self): """ Evaluates the current list of cards and returns a total integer value""" total = 0 if self.is_blackjack() == True: return else: for c in self.cards: for c1 in c: for c2 in c1[1:]: if c2.isdigit(): total += int(c2) elif 'A' == c2: total += 11 else: total += 10 print('Current card total: ', total, '\n') return total def is_blackjack(self): """ Takes in 2 cards and returns True if the cards contain only 1x Ace and either 10, J, Q or K """ if len(self.cards[0]) == 2: c1 = self.pic_to_int(self.cards[0][0][1]) c2 = self.pic_to_int(self.cards[0][1][1]) total = c1 + c2 if c1 or c2 else 0 if total == 21: print('BLACKJACK!!!!') return else: return False else: return False def check_if_bust(self): score = self.current_score() bust = False if score > 21: bust = True print("Bust!") return bust return bust def stick_or_twist(self, twist=False): """ Takes in current hand and processes a new card returns ok or bust """ score = self.current_score() cards = self.cards if self.player == 'Dealer': if score < 17: cards[0].append(i.pop()) self.check_if_bust() else: print('Dealer must stand on 17') elif self.player != 'Dealer': cards[0].append(i.pop()) self.check_if_bust() def split_pair(self): """ splits a pair of the same cards into 2 games """ pass player1 = Player([v for k, v in players.items() if 'Player1' == k], 'Player1') player2 = Player([v for k, v in players.items() if 'Player2' == k], 'Player2') dealer = Player([v for k, v in players.items() if 'Dealer' == k], 'Dealer') player_list = [player1, player2, dealer] for p in player_list: print(p.player, ':') p.is_blackjack() p.current_score() p.check_if_bust() p.stick_or_twist(twist=True) print(len(i), 'cards left') print_current_cards(players) # for x in range(3): # j = i.pop() # print(j) # print(len(i), 'cards left')