5
\$\begingroup\$

Code below, very new to python, would love some constructive criticism, mainly in relation to what I could have improved on, if my use of aces (where I subtract 10) is smart, and my use of functions?

The way my code works is it starts by dealing 2 cards to both the dealer and the user, this is done randomly, it then asks the user if they want another card...if they say no, the dealer gets their cards dealt, if they type yes, then they get another card and asked the question again. Aces I had trouble with utilizing so I basically just subtracted 10 from everyone who went over 21 because it's basically how people play blackjack (no one opts for a 1 if they can opt for an 11 and stay equal to or under 21).

For those wondering about the rules: Blackjack (twenty-one) is a casino game played with cards. The goal of the game to draw cards that total as close to 21 points as possible without going over. All face cards count as 10 points, aces count as 1 or 11, and all other cards count their numeric value.

The game is played against a dealer. The player tries to get closer to 21 (without going over) than the dealer. If the dealer busts (goes over 21) the player automatically wins (provided the player had not already busted). The dealer must always take cards according to a fixed set of rules. The dealer takes cards until he or she achieves a total of at least 17. If the dealer's hand contains an ace, it will be counted as 11 when that results in a total between 17 and 21 inclusive; otherwise, the ace is counted as 1.

import random
deck =(2,3,4,5,6,7,8,9,10,10,10,10,11) # main deck tuple including aces (aces become 1 if user > 21)
dealer_hand = [] # dealer list to hold cars
user_hand = [] # user list to hold cards
 
def draw(): # function that will be called to draw a random card from the deck
 new_card = random.choice(deck)
 return new_card
def dealer_draw(user_total):
 if user_total < 21:
 while sum(dealer_hand) < 17:
 dealer_hand.append(draw())
 return dealer_hand
def blackjack(): # game fuction
 for i in range(2): # for loop to draw 2 cards to both the user and dealer
 user_hand.append(draw())
 dealer_hand.append(draw())
 
 print(f'User has: {user_hand}')
 print(f'Dealer has: {dealer_hand}')
 
 continue_game = True # will be used to terminate while loop
 
 while continue_game == True and sum(user_hand) < 21:
 drawing = input("Would you like to draw another card (y/n) : ").lower()
 
 if drawing == 'y': # if users types y, it draws another card
 user_hand.append(draw())
 
 if 11 in user_hand and sum(user_hand) > 21: # aces (11's) get converted to 1's if > 21
 user_hand.remove(11)
 user_hand.append(1)
 
 print(f'User now has has: {user_hand}')
 print(f'Dealer has: {dealer_hand}')
 
 else:
 continue_game = False 
 
 dealer_draw(sum(user_hand)) # Function to draw card for dealer (if necessary)
 
 print("~~~~~~~~~~~~~~~~~ Final results ~~~~~~~~~~~~~~~~~")
 print(f"User has {user_hand} for a total of {sum(user_hand)}")
 print(f"Dealer has {dealer_hand} for a total of {sum(dealer_hand)}")
 
 if sum(user_hand) > 21: #if statements check for bust, then draws, then checks for values between user/dealer 
 print("User busts! Dealer wins")
 elif sum(user_hand) == sum(dealer_hand):
 print("Draw")
 elif sum(dealer_hand) > sum(user_hand) and sum(dealer_hand) <= 21:
 print("Dealer wins")
 else:
 print("User wins")
 
# Main Game
print('____________________________________________________________________')
print(" Welcome to Blackjack ")
print("Blackjack is a card game where the user goes against the dealer.")
print("Your Goal is to draw cards to get closest to 21 points,")
print("however you don't want to go above 21 points because you will lose!")
play_game = False
while play_game == False:
 play = input(" Would you like to play? (y/n) : ").lower()
 if play == "y":
 blackjack()
 play_game = True
 elif play == "n":
 print('_______________________________________________________________')
 print("Goodbye")
 play_game = True
 else:
 print("You did not enter either 'y' or 'n'.")
Reinderien
70.9k5 gold badges76 silver badges256 bronze badges
asked Jun 4, 2022 at 6:30
\$\endgroup\$
3
  • \$\begingroup\$ First thing I can see is the variable play_game and while play_game == False: - it's kinda confusing and could use a different name like valid_option_chosen. \$\endgroup\$ Commented Jun 4, 2022 at 9:40
  • \$\begingroup\$ I also just noticed a bug: Aces get converted to 1 for the user, but not the bank. \$\endgroup\$ Commented Jun 4, 2022 at 11:26
  • \$\begingroup\$ In regular blackjack, between one and eight standard 52-card decks are shuffled together. In your code, you're drawing with replacement, which is equivalent to pulling out a fresh deck for every card drawn. Is that intentional? \$\endgroup\$ Commented Jun 4, 2022 at 16:11

1 Answer 1

3
\$\begingroup\$

In regards to your question of your use of functions: I think you under utilize them. Note that I could remove a lot of your comments because it is clear from the code what the code does, just by extracting functions and naming them appropriately (i would recommend the chapter Naming Conventions from Uncle Bobs Clean Code). I think your solution with the aces is fine.

Oh and I also moved everything into a class so it's easier to restart the game by just initializing a new instance. This way the game can be played more than once without restarting the whole application.

import random
def draw_for(hand):
 deck = (2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11) # main deck tuple including aces (aces become 1 if user > 21)
 new_card = random.choice(deck)
 hand.append(new_card)
class BlackJack:
 def __init__(self):
 self.user_hand = None # init so pycharm doesn't warn
 self.dealer_hand = None
 def play(self): # game function
 self.reset()
 self.draw_starter_cards()
 self.print_hands()
 self.main_action()
 self.dealer_draw_to_limit()
 self.print_final_hands()
 self.print_winner()
 def reset(self):
 self.dealer_hand = []
 self.user_hand = []
 def main_action(self): # could use a better name
 continue_game = True
 while continue_game and not self.user_busted():
 drawing = input("Would you like to draw another card (y/n) : ").lower()
 if drawing == 'y':
 self.user_draws()
 self.print_hands()
 else:
 continue_game = False
 def user_busted(self):
 return sum(self.user_hand) > 21
 def user_draws(self):
 draw_for(self.user_hand)
 if self.user_has_aces() and self.user_busted():
 self.convert_aces()
 def user_has_aces(self):
 return 11 in self.user_hand
 def convert_aces(self):
 self.user_hand.remove(11)
 self.user_hand.append(1)
 def dealer_draw_to_limit(self):
 if not self.user_busted():
 while sum(self.dealer_hand) < 17:
 draw_for(self.dealer_hand)
 return self.dealer_hand
 def print_winner(self):
 if self.user_busted():
 print("User busts! Dealer wins")
 elif sum(self.user_hand) == sum(self.dealer_hand):
 print("Draw")
 elif sum(self.user_hand) < sum(self.dealer_hand) <= 21:
 print("Dealer wins")
 else:
 print("User wins")
 def print_final_hands(self):
 print("~~~~~~~~~~~~~~~~~ Final results ~~~~~~~~~~~~~~~~~")
 print(f"User has {self.user_hand} for a total of {sum(self.user_hand)}")
 print(f"Dealer has {self.dealer_hand} for a total of {sum(self.dealer_hand)}")
 def print_hands(self):
 print(f'User has: {self.user_hand}')
 print(f'Dealer has: {self.dealer_hand}')
 def draw_starter_cards(self):
 for i in range(2):
 draw_for(self.user_hand)
 draw_for(self.dealer_hand)
answered Jun 4, 2022 at 10:27
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.