I created this blackjack program which I'm looking for feedback, both with the code and how the program itself works. I'm also looking to see if my code could be faster or cleaner before I compile it using Cython.
I've used three files: main.py, class_handler.py and account_handler.py. For clarity, I've seperated them into different code blocks.
I previously made a post here, but I didn't format it properly. Sorry about that...
Any and all criticism is appreciated!
# class_handler.py
import random
suit_list = ["Hearts", "Diamonds", "Spades", "Clubs"]
value_list = [2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K", "Ace"]
class Card:
def __init__(self, suit, value):
self.suit = suit
self.value = value
def __repr__(self):
return f"{self.value} of {self.suit}"
class Deck:
deck = []
def __init__(self, nof_card_packs, shuffled):
for pack in range(nof_card_packs):
self.deck += [Card(suit, value) for value in value_list for suit in suit_list]
if shuffled is True:
random.shuffle(self.deck)
def __str__(self):
return f"{len(self.deck)} cards in deck."
def show_entire_card_deck(self):
for i in range(len(self.deck)):
print(self.deck[i])
class Player:
username = ""
is_dealer = False
total_score = 0
ace_counter = 0
blackjack_flag = False
bust_flag = False
account = 0
hands_played = 0
hands_won = 0
def __init__(self, is_dealer):
self.is_dealer = is_dealer
self.hand = []
self.draw_cards()
def __str__(self):
if self.is_dealer:
return f"Dealer is showing the following card: {self.hand[0]}"
else:
return f"You have are showing the following cards:\n{self.hand}" \
f"\nYour total value is: {self.total_score}."
def draw_cards(self):
self.hand.append(Deck.deck[0])
Deck.deck.pop(0)
self.hand.append(Deck.deck[0])
Deck.deck.pop(0)
self.determine_card_values()
def determine_card_values(self):
self.total_score = 0
for card in range(len(self.hand)):
if self.hand[card].value == "Ace":
self.ace_counter += 1
self.total_score += 11
elif self.hand[card].value in ["J", "Q", "K"]:
self.total_score += 10
else:
self.total_score += int(self.hand[card].value)
if self.total_score > 21:
if self.ace_counter >= 1:
self.ace_counter -= 1
self.total_score -= 10
else:
print("-----\nBust!\n-----")
self.bust_flag = True
break
def deal_card(self):
self.hand.append(Deck.deck[0])
Deck.deck.pop(0)
print(self.hand[len(self.hand) - 1])
self.determine_card_values()
def player_actions(self):
if self.blackjack_flag:
pass
else:
while True:
if self.total_score == 21:
print("BLACKJACK!")
break
print(self, "\n")
console = str(input("Hit or stand?\n>"))
console.lower()
if console == "hit":
self.deal_card()
if self.bust_flag:
print(f"You've gone bust:\nHand:{self.hand}\nTotal value:{self.total_score}")
break
elif console == "stand":
break
def dealer_actions(self, player):
print(self, "and", self.hand[1])
while True:
if not self.total_score > player.total_score:
if self.bust_flag:
print(f"Dealer went bust:\nHand: {self.hand}\nTotal value: {self.total_score}")
break
if self.total_score < 17:
self.deal_card()
else:
print(f"Dealer stands on {self.total_score}")
break
else:
print(f"Dealer stands on {self.total_score}")
break
def determine_winner(self, dealer):
print(f"""
---------------------------------------------------- GAME OVERVIEW -----------------------------------------------------
At the end of the game, you had a hand of {self.hand} and a total score of {self.total_score}.
The dealer had a hand of {dealer.hand} and a total score of {dealer.total_score}.""")
if not self.bust_flag:
if not dealer.bust_flag:
if self.total_score == dealer.total_score:
print("Draw!")
elif self.total_score > dealer.total_score:
print("You win!")
else:
print("You lose!")
self.hands_won += 1
else:
print("You win!")
self.hands_won += 1
else:
print("You lose!")
self.hands_played += 1
print("""
--------------------------------------------------------------------------------------------------
""")
def show_stats(self):
print(f"""
------------- BASIC INFO -------------
Username: {self.username}
Bank Account: {self.account}
---------- PLAYER STATISTICS ---------
Hands played: {self.hands_played}
Hands won: {self.hands_won}
--------------------------------------""")```
# --------------------------------------------------------------------------------
# account_handler.py
def create_account():
"""Creates a new account for the player, with 1500 chips."""
username = str(input("Enter a username.\n>"))
user_profile = open(username + ".txt", "w")
user_profile.write(f"""
------------- BASIC INFO -------------
Username: {username}
Bank Account: 1500
---------- PLAYER STATISTICS ---------
Hands played: 0
Hands won: 0
--------------------------------------
{username},1500,0,0""")
user_profile.close()
print("Account created successfully!")
def write_account(profile):
"""Saves changes to the current account."""
username = str(input("Enter a username.\n>"))
user_profile = open(username + ".txt", "w")
file_info = (f"""
------------- BASIC INFO -------------
Username: {username}
Bank Account: {profile.account}
---------- PLAYER STATISTICS ---------
Hands played: {profile.hands_played}
Hands won: {profile.hands_won}
--------------------------------------
{username},{profile.account},{profile.hands_played},{profile.hands_won}""")
user_profile.write(file_info)
user_profile.close()
print("File written successfully!")
def load_account(profile):
"""Loads changes from account."""
username = str(input("Enter a username.\n>"))
user_profile = open(username + ".txt", "r")
str_info = user_profile.readlines()[8]
info = str_info.split(",")
print(info)
profile.username = info[0]
profile.account = info[1]
profile.hands_played = info[2]
profile.hands_won = info[3]
user_profile.close()
print("File loaded successfully!")```
--------------------------------------------------------------------------------------------------
# main.py
from class_handler import *
from account_handler import *
import os
def setup_game():
"""Sets up the initial game."""
Deck(shuffled=True, nof_card_packs=5)
player_f = Player(False)
dealer_f = Player(True)
return player_f, dealer_f
def help_with_cmds(console_input):
"""Gets help with the current commands. Supports two words (e.g. 'help clear')"""
if len(console_input) > 1:
if console_input[1] == "close":
print(close.__doc__)
elif console_input[1] == "play":
print(play.__doc__)
elif console_input[1] == "createacc":
print(create_account.__doc__)
elif console_input[1] == "saveacc":
print(write_account.__doc__)
elif console_input[1] == "loadacc":
print(load_accoutn.__doc__)
elif console_input[1] == "clear":
print(clear.__doc__)
elif console_input[1] == "stats":
print(stats.__doc__)
elif console_input[1] == "help":
print(help_with_cmds.__doc__)
else:
print("Unrecognised input, please try again.")
else:
print("""Available commands:
close
play
createacc
saveacc
loadacc
clear
stats""")
def clear():
"""Clears the screen. Your mileage may vary!"""
if os.name == "nt":
os.system("cls")
else:
os.system("clear")
def close():
"""Closes the program.
Available inputs:
Yes, yes, y: closes the program.
Anything else: cancels the shutdown."""
console1 = str(input("!!! ANY UNSAVED STATS WILL BE LOST !!\nAre you sure?\nCl>"))
console1.lower()
if console1 == "yes" or "y":
quit()
else:
print("Cancelling shutdown.")
def play():
"""Plays the main blackjack game once."""
player, dealer = setup_game()
print(dealer, "\n")
player.player_actions()
if not player.bust_flag:
dealer.dealer_actions(player)
player.determine_winner(dealer=dealer)
def console():
player, dealer = setup_game()
console_input = str(input(">"))
console_input.lower()
if console_input.__contains__("help"):
console_input_list = console_input.split()
help_with_cmds(console_input_list)
elif console_input == "close":
close()
elif console_input == "play":
play()
elif console_input == "createacc":
create_account()
elif console_input == "saveacc":
write_account(player)
elif console_input == "loadacc":
load_account(player)
elif console_input == "clear":
clear()
elif console_input == "stats":
player.show_stats()
else:
print("Unrecognised command. Please try again.")
if __name__ == "__main__":
print("Beginners Poker. Enter an option.")
while True:
console()```