Hello Campers!
After watching one of fCC’s python tutorials on youtube (This one) I did the follow along project for the terminal based blackjack game, and while the game was fun and the project good for showing off what the course taught, I felt like there could be some improvements made to the game itself that would make it far more enjoyable to actually play.
So after a few hours of tinkering that let my stretch my baby dev legs a bit more, I came up with this:
import random
import os
rank_value = {"A" : 11, "2" : 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, "9" : 9, "10" : 10, "J" : 10, "Q" : 10, "K" : 10}
class Card:
def __init__(self, suit, rank):
self.suit = suit
self.rank = rank
def front_face(self) -> list:
if self.rank != "10":
front_face = [
f" _____ ",
f"|{self.rank} |",
f"| {self.suit} |",
f"| {self.rank}|",
f" ‾‾‾‾‾ "
]
else:
front_face = [
f" _____ ",
f"|{self.rank} |",
f"| {self.suit} |",
f"| {self.rank}|",
f" ‾‾‾‾‾ "
]
return front_face
def back_face(self) -> list:
back_face = [
" _____ ",
"| p |",
"| pod |",
"| d |",
" ‾‾‾‾‾ "
]
return back_face
def __str__(self):
return f"{self.rank} of {self.suit}"
class Deck:
def __init__(self):
self.cards = []
suits = ["♠", "♥", "♣", "♦"]
ranks = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
for suit in suits:
for rank in ranks:
self.cards.append(Card(suit, rank))
def shuffle(self):
if len(self.cards) > 1:
random.shuffle(self.cards)
def deal(self, number: int):
cards_delt = []
for i in range(number):
if len(self.cards) > 0:
cards_delt.append(self.cards.pop())
return cards_delt
class Hand:
def __init__(self, dealer = False):
self.cards = []
self.value = 0
self.dealer = dealer
def add_card(self, card_list: list):
self.cards.extend(card_list)
def calculate_value(self):
self.value = 0
ace_count = 0
for card in self.cards:
card_value = int(rank_value[card.rank])
self.value += card_value
if card.rank == "A":
ace_count += 1
while ace_count > 0:
if self.value > 21:
self.value -= 10
ace_count -= 1
def get_value(self):
self.calculate_value()
return self.value
def is_blackjack(self):
return self.get_value() == 21
def display(self, show_facedown_cards = False):
hand_matrix = []
hand_string = ""
print(f'''{"Dealer's" if self.dealer else "Your"} hand:''')
for index, card in enumerate(self.cards):
if self.dealer and index == 0 and not show_facedown_cards and not self.is_blackjack():
hand_matrix.append(card.back_face())
else:
hand_matrix.append(card.front_face())
for i in range(5):
for e in range(len(hand_matrix)):
hand_string += hand_matrix[e][i]
hand_string += "\n"
print(hand_string)
if not self.dealer:
print("Value:", self.get_value())
print()
class Game:
def __init__(self):
self.wins = 0
self.losses = 0
self.ties = 0
self.games = 0
self.score = 0
self.high_score = 0
self.low_score = 0
self.play_response = ""
def start_screen(self):
print("-" * 50)
print(" " * 11 + "Welcome to BlackJack.py!")
print("-" * 50)
print()
self.play_response = input("Would you like to be dealt in? [Y/N]: ").lower()
while self.play_response not in ["yes", "y", "no", "n"]:
print("Invalid input!\n")
self.play_response = input("Would you like to be dealt in? [Please enter 'Yes', 'Y', 'No', or 'N']: ").lower()
if self.play_response in ["yes", "y"]:
clear_terminal()
self.play()
else:
clear_terminal()
print("Good bye!")
def display_header(self):
print("-" * 50)
print(f"Game: {self.games} Wins: {self.wins} Losses: {self.losses} Ties: {self.ties} Score: {self.score}")
print("-" * 50)
def display_board(self, dealer_hand: Hand, player_hand: Hand):
dealer_hand.display()
print("-" * 50 + "\n")
player_hand.display()
def display_dealer_board(self, dealer_hand: Hand, player_hand: Hand):
dealer_hand.display(show_facedown_cards=True)
print(f"Dealer's Value: {dealer_hand.get_value()}")
print("-" * 50 + "\n")
player_hand.display()
def play(self):
while self.play_response in ["y", "yes"]:
self.games += 1
deck = Deck()
deck.shuffle()
player_hand = Hand()
dealer_hand = Hand(dealer=True)
for i in range(2):
player_hand.add_card(deck.deal(1))
dealer_hand.add_card(deck.deal(1))
clear_terminal()
self.display_header()
self.display_board(dealer_hand, player_hand)
choice = ""
while player_hand.get_value() < 21 and choice not in ["s", "stand"]:
choice = input("'Hit' or 'Stand'?: ").lower()
print()
while choice not in ["h", "s", "hit", "stand"]:
print("Invalid input!")
choice = input("Please enter 'Hit' or 'H' OR 'Stand' or 'S' as valid input: ").lower()
print()
if choice in ["hit", "h"]:
player_hand.add_card(deck.deal(1))
#player_hand.display()
clear_terminal()
self.display_header()
self.display_board(dealer_hand, player_hand)
dealer_hand_value = dealer_hand.get_value()
if player_hand.get_value() <= 21 and player_hand.get_value() > dealer_hand_value:
while dealer_hand_value < 17:
dealer_hand.add_card(deck.deal(1))
dealer_hand_value = dealer_hand.get_value()
clear_terminal()
self.display_header()
self.display_dealer_board(dealer_hand, player_hand)
self.check_winner(player_hand, dealer_hand)
if self.score > self.high_score:
self.high_score = self.score
if self.score < self.low_score:
self.low_score = self.score
self.play_response = input("Would you like to play another game? [Y/N]: ").lower()
while self.play_response not in ["yes", "y", "no", "n"]:
print("Invalid input!\n")
self.play_response = input("Would you like to play another game? [Please enter 'Yes', 'Y', 'No', or 'N']: ").lower()
clear_terminal()
print("Thanks for playing!\n")
print(f"Overall:\nGames: {self.games}\nWins: {self.wins}\nLosses: {self.losses}\nTies: {self.ties}\n")
print(f"End score: {self.score}\nLargest Stack: {self.high_score}\nDeepest in the hole: {self.low_score}\n")
def check_winner(self, player_hand: Hand, dealer_hand: Hand):
if player_hand.is_blackjack() and dealer_hand.is_blackjack():
print("Dealer and Player both Blackjack! It's a tie.")
self.ties += 1
elif player_hand.is_blackjack():
print("You got blackjack! You win!")
self.wins += 1
self.score += 3
elif dealer_hand.is_blackjack():
print("Dealer has blackjack! Dealer wins!")
self.losses += 1
self.score -= 3
elif player_hand.get_value() > 21:
print("You busted. Dealer wins!")
self.losses += 1
self.score -= 2
elif dealer_hand.get_value() > 21:
print("Dealer busted! You win!")
self.wins += 1
self.score += 2
elif player_hand.get_value() > dealer_hand.get_value():
self.wins += 1
self.score += 1
print("You win!")
elif player_hand.get_value() == dealer_hand.get_value():
self.ties += 1
print("It's a tie.")
else:
self.losses += 1
self.score -= 1
print("Dealer wins!")
def clear_terminal():
os.system('cls' if os.name == 'nt' else 'clear')
if __name__ == "__main__":
game = Game()
game.start_screen()
Here are some screenshots of the game in action:
The end screen:
I’m just patting myself on the back here for a pretty basic achievement but I am open to any feedback on the changes I made!
Thank you for taking the time to read my post and look over my code.






