Write a text based Blackjack game.
My Solution:
import random # needed to draw a random item from the list
from art import logo
import os
# sets up the card we can play with
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
def deal_card():
"""Returns a random card from the deck"""
card = random.choice(cards)
return card
def check_ace(cards):
"""Take a list of cards and check of the ace should be 1 or 11"""
if 11 in cards and sum(cards) > 21:
cards.remove(11)
cards.append(1)
return sum(cards)
def is_blackjack(hand):
"""Take a list of cards and return True if it's a blackjack, False otherwise"""
# NOTE I did not include checks for only two cards - I need to revisit this, but
# it is used in result which takes scores not cards so needs adjusting as well
if sum(hand) == 21 and len(hand) == 2:
return True
else:
return False
def is_bust(score):
"""Take a score and return True if the score is over 21, False otherwise"""
if score > 21:
return True
else:
return False
def result(u_score, c_score):
"""Take two scores and compare them to determine the winner"""
# define complex messages
player_win = f"\n{'*' * 20} \n You win \n{'*' * 20}"
dealer_win = f"\n{'*' * 20} \n Dealer wins \n{'*' * 20}"
draw = f"\n{'*' * 20} \n !Draw! \n{'*' * 20}"
player_bust = f"\n{'*' * 20} \n Your score {u_score}. You Bust. You lose \n{'*' * 20}"
dealer_bust = f"\n{'*' * 20} \n Dealer score {c_score}. Dealer Bust. You win \n{'*' * 20}"
if u_score > c_score and not is_bust(u_score):
return player_win
elif c_score > u_score and not is_bust(c_score):
return dealer_win
elif u_score == c_score:
return draw
elif is_bust(u_score):
return player_bust
elif is_bust(c_score):
return dealer_bust
def play_game():
"""Play a single game of blackjack"""
# Setup empty lists to hold each players cards
user_cards = []
dealer_cards = []
# set the game_over token to false
is_game_over = False
# deal the first two cards
# the _ can be used when you don't need the value in range inside the loop
# for example: for i in range(2): would work but we never need to know the value of i
# so we can use an underscore instead
for _ in range(2):
user_cards.append(deal_card())
dealer_cards.append(deal_card())
# play the game until it ends
while not is_game_over:
# calculate the scores from the list items
user_score = check_ace(user_cards)
dealer_score = check_ace(dealer_cards)
print(f"User cards {user_cards} Total {user_score}")
print(f"Dealers first card {dealer_cards[0]}")
# Check if either player has blackjack. if they do the game ends
if is_blackjack(dealer_cards):
is_game_over = True
return result(user_score, dealer_score)
elif is_blackjack(user_cards):
is_game_over = True
return result(user_score, dealer_score)
if is_game_over: # This would be true if either player had blackjack or had already bust.
return result(user_score, dealer_score)
else: # If neither player has blackjack or has gone bust, the user needs to decide if they want more cards
# Ask the user if they want another card
user_should_deal = input("++Type 'y' to get another card, type 'n' to pass: ")
while user_should_deal == "y" and not is_game_over: # as long as the user say yes
user_cards.append(deal_card()) # deal another card to the dealer
user_score = check_ace(user_cards) # calculate the score and check for aces
if is_bust(user_score): # check user score for > 21
print(f"User's cards {user_cards} Total {user_score}.")
is_game_over = True
return result(user_score, dealer_score)
else: # if not == 21 nor > 21
print(f"Player's cards {user_cards} Total {user_score}.")
user_should_deal = input("--Type 'y' to get another card, type 'n' to pass: ") # ask if they want another card
while dealer_score < 17 and not is_game_over: # One the player has stopped taking cards. If the game has not ended
dealer_cards.append(deal_card()) # deal another card to the dealer
dealer_score = check_ace(dealer_cards) # add up the dealers score
if is_bust(dealer_score): # check for bust
print("dealer bust")
is_game_over = True
return result(user_score, dealer_score)
# once the dealer score > 17 stop
print(f"User's cards {user_cards} Total {user_score}.") # print the hands
print(f"Dealer's cards {dealer_cards} Total {dealer_score}.") # print the scores'
return result(user_score, dealer_score) # calculate and print the result
play = 'y'
print(logo)
while play == 'y':
message = play_game()
print(message)
play = input("\nDo you want to play again? (y/n): ")
if play == 'n':
print("Thanks for playing!")
else:
os.system('cls')
print(logo)