I've decided to learn python as my main language and after watching some tutorial on youtube I decided to write this blackjack game using OOP. Im sure it has a lot of beginner mistakes and might be simply bad. I also don't guarantee that it will always work but i would appreciate any feedback you could give me that could help me write better and cleaner code in the future.
Thanks in advance.
from random import randint
from os import system
class Deck:
def __init__(self):
self.deck = [("Ace of Clubs", 1), ("Ace of Diamonds", 1),
("Ace of Hearts", 1), ("Ace of Spades", 1),
("2 of Clubs", 2), ("2 of Diamonds", 2),
("2 of Hearts", 2), ("2 of Spades", 2),
("3 of Clubs", 3), ("3 of Diamonds", 3),
("3 of Hearts", 3), ("3 of Spades", 3),
("4 of Clubs", 4), ("4 of Diamondss", 4),
("4 of Hearts", 4), ("4 of Spades", 4),
("5 of Clubs", 5), ("5 of Diamonds", 5),
("5 of Hearts", 5), ("5 of Spades", 5),
("6 of Clubs", 6), ("6 of Diamonds", 6),
("6 of Hearts", 6), ("6 of Spades", 6),
("7 of Clubs", 7), ("7 of Diamonds", 7),
("7 of Hearts", 7), ("7 of Spades", 7),
("8 of Clubs", 8), ("8 of Diamonds", 8),
("8 of Hearts", 8), ("8 of Spades", 8),
("9 of Clubs", 9), ("9 of Diamonds", 9),
("9 of Hearts", 9), ("9 of Spades", 9),
("10 of Clubs", 10), ("10 of Diamonds", 10),
("10 of Hearts", 10), ("10 of Spades", 10),
("Jack of Clubs", 10), ("Jack of Diamonds", 10),
("Jack of Hearts", 10), ("Jack of Spades", 10),
("Queen of Clubs", 10), ("Queen of Diamonds", 10),
("Queen of Hearts", 10), ("Queen of Spades", 10),
("King of Clubs", 10), ("King of Diamonds", 10),
("King of Hearts", 10), ("King of Spades", 10)]
def get_deck(self):
return self.deck
def remove_from_deck(self, index):
self.deck.pop(index)
def __len__(self):
return len(self.deck)
class Tokens:
def __init__(self, amount):
self.amount = amount
def __str__(self):
return str(self.amount)
def bet_tokens(self, amount):
if self.amount - amount >= 0:
self.amount -= amount
return True
print(f"Not enough tokens!")
return False
def add_tokens(self, amount_won):
self.amount += amount_won
def get_tokens(self):
return self.amount
class Blackjack:
def __init__(self,):
self.tokens = Tokens(100)
self.second_card_hidden = True
def deal_a_card(self, hand, deck):
x = randint(0, len(self.deck) - 1)
hand.append(deck.get_deck()[x])
deck.remove_from_deck(x)
def open(self, bet_amount):
if self.tokens.bet_tokens(bet_amount):
self.deal_a_card(self.user_hand, self.deck)
self.deal_a_card(self.user_hand, self.deck)
self.deal_a_card(self.dealer_hand, self.deck)
self.deal_a_card(self.dealer_hand, self.deck)
return True
return False
def get_sum_of_cards(self, hand):
sum_of_cards = 0
for card in hand:
sum_of_cards += card[1]
for card in hand:
if card[0] in ["Ace of Spades", "Ace of Hearts", "Ace of Diamonds", "Ace of Clubs"]:
if sum_of_cards <= 11:
sum_of_cards += 10
return sum_of_cards
def check_for_bust(self, hand):
return self.get_sum_of_cards(hand) > 21
def get_cards(self, hand):
cards = ""
for card in hand:
cards += card[0] + ", "
return cards[:-2]
def reset_hands_and_deck(self):
self.deck = Deck()
self.user_hand = []
self.dealer_hand = []
self.second_card_hidden = True
def clear_screen_print_cards(self):
system("cls")
print(self)
def check_for_win(self):
user_score = self.get_sum_of_cards(self.user_hand)
dealer_score = self.get_sum_of_cards(self.dealer_hand)
if user_score == dealer_score:
print("Tie!")
return "tie"
elif user_score > dealer_score:
print("You win!")
return "win"
elif dealer_score > user_score:
print("You lose!")
return "lose"
def check_for_blackjack(self):
user_score = self.get_sum_of_cards(self.user_hand)
dealer_score = self.get_sum_of_cards(self.dealer_hand)
if user_score == dealer_score == 21:
print("You both hit a blackjack!")
return "tie"
elif user_score == 21:
print(f"You hit a blackjack!")
return "blackjack_user"
elif dealer_score == 21:
system("cls")
self.second_card_hidden = False
print(game)
print("Dealer hit a blackjack!")
return "blackjack_dealer"
return 0
def hit_or_stand(self):
decision = input("(hit/stand h/s): ")
while decision.lower() not in ["hit", "h", "stand", "s"]:
decision = input("(hit/stand h/s): ")
if decision in ["hit", "h"]:
return 1
return 0
def token_distributor(self, result, bet_amount):
if result == "blackjack_user":
self.tokens.amount += bet_amount + 1.5 * bet_amount
elif result == "tie":
self.tokens.amount += bet_amount
elif result == "win":
self.tokens.amount += (2 * bet_amount)
def __str__(self):
if self.second_card_hidden:
return f"\tDealer hand({self.dealer_hand[1][1]})\n[{self.dealer_hand[1][0]}, <card hidden>]\n\n[{self.get_cards(self.user_hand)}]\n\tPlayer hand({self.get_sum_of_cards(self.user_hand)})\n"
else:
return f"\tDealer hand({self.get_sum_of_cards(self.dealer_hand)})\n[{self.get_cards(self.dealer_hand)}]\n\n[{self.get_cards(self.user_hand)}]\n\tPlayer hand({self.get_sum_of_cards(self.user_hand)})\n"
def play_blackjack(game):
game.reset_hands_and_deck()
system("cls")
print(f"Welcome to Blackjack!, Your tokens: {game.tokens.get_tokens()}")
bet_amount = input(
f"How much do u want to bet? max({game.tokens.get_tokens()}): ")
while (not bet_amount.isdigit()) or (int(bet_amount) not in range(1, game.tokens.get_tokens() + 1)):
system("cls")
bet_amount = input(
f"How much do u want to bet? max({game.tokens.get_tokens()}): ")
bet_amount = int(bet_amount)
system("cls")
if game.open(bet_amount):
print(game)
check = game.check_for_blackjack()
if check:
game.token_distributor(check, bet_amount)
return 1
elif not check:
while game.hit_or_stand():
game.deal_a_card(game.user_hand, game.deck)
if game.get_sum_of_cards(game.user_hand) == 21:
game.token_distributor("win", bet_amount)
if game.check_for_bust(game.user_hand):
game.clear_screen_print_cards()
print("Bust!")
return 1
game.clear_screen_print_cards()
game.second_card_hidden = False
while game.get_sum_of_cards(game.dealer_hand) < 17:
game.deal_a_card(game.dealer_hand, game.deck)
if game.check_for_bust(game.dealer_hand):
game.clear_screen_print_cards()
print("Dealer bust!")
game.tokens.amount += bet_amount * 2
return 1
game.clear_screen_print_cards()
check = game.check_for_win()
if check:
game.token_distributor(check, bet_amount)
return 1
game = Blackjack()
play_again = True
while play_again:
play_blackjack(game)
play_again = True if input(
f"You have {game.tokens.get_tokens()} tokens left\nPlay again? (y/n): ").lower() == "y" else False
system("cls")
print(f"Game over!, your ended up with {game.tokens.get_tokens()} tokens")