DEV Community

Joose
Joose

Posted on

First Post

I just wrote a script for a terminal based blackjack script. It is not perfect believe me, but I have the functionality for a full game of blackjack.

import random

class Player:
def init(self, name, balance):
self.name = name
self.balance = balance
self.hand = []

def place_bet(self, amount):
    if amount > self.balance:
        raise ValueError("Bet amount cannot exceed current balance.")
    self.balance -= amount
    return amount

def receive_card(self, card):
    self.hand.append(card)

def clear_hand(self):
    self.hand = []

def calculate_score(self):
    score = sum(BlackjackGame.card_values[card] for card in self.hand)
    aces = self.hand.count('A')
    while score > 21 and aces:
        score -= 10
        aces -= 1
    return score

def display_hand(self):
    print(f"{self.name}'s hand: {' '.join(self.hand)} (Score: {self.calculate_score()})")
Enter fullscreen mode Exit fullscreen mode

class Dealer:
def init(self):
self.hand = []

def receive_card(self, card):
    self.hand.append(card)

def clear_hand(self):
    self.hand = []

def calculate_score(self):
    score = sum(BlackjackGame.card_values[card] for card in self.hand)
    aces = self.hand.count('A')
    while score > 21 and aces:
        score -= 10
        aces -= 1
    return score

def display_hand(self, show_all=False):
    if show_all:
        print(f"Dealer's hand: {' '.join(self.hand)} (Score: {self.calculate_score()})")
    else:
        print(f"Dealer's hand: {self.hand[0]} ?")
Enter fullscreen mode Exit fullscreen mode

class BlackjackGame:
card_values = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'J': 10, 'Q': 10, 'K': 10, 'A': 11}

def __init__(self, player_name, initial_balance=1000):
    self.player = Player(player_name, initial_balance)
    self.dealer = Dealer()
    self.deck = self.create_deck()
    random.shuffle(self.deck)
    self.player_hand_visible = False

def create_deck(self):
    return ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] * 4

def deal_card(self):
    if not self.deck:
        self.deck = self.create_deck()
        random.shuffle(self.deck)
    return self.deck.pop()

def play_hand(self, hand, bet):
    self.player.display_hand()
    first_action = True
    while self.player.calculate_score() < 21:
        if first_action and len(hand) == 2:
            action = input("Do you want to [h]it, [s]tand, [d]ouble down, or [sp]lit? ").lower()
        else:
            action = input("Do you want to [h]it or [s]tand? ").lower()

        if action == 'h':
            self.player.receive_card(self.deal_card())
            self.player.display_hand()
            first_action = False
        elif action == 'd' and first_action:
            if bet * 2 <= self.player.balance:
                bet *= 2
                self.player.receive_card(self.deal_card())
                self.player.display_hand()
                break
            else:
                print("You can only double down if you have enough balance.")
        elif action == 'sp' and first_action and self.player.hand[0] == self.player.hand[1]:
            if bet * 2 <= self.player.balance:
                return 'split'
            else:
                print("You can only split if you have enough balance.")
        else:
            break

    return self.player.hand, bet

def play(self):
    print("Welcome to Blackjack!")

    while self.player.balance > 0:
        print(f"Your current balance is: ${self.player.balance}")
        try:
            bet = self.player.place_bet(int(input("Place your bet: ")))
        except ValueError as e:
            print(e)
            continue

        # Clear hands and deal initial cards
        self.player.clear_hand()
        self.dealer.clear_hand()

        self.player.receive_card(self.deal_card())
        self.player.receive_card(self.deal_card())
        self.dealer.receive_card(self.deal_card())
        self.dealer.receive_card(self.deal_card())

        self.player.display_hand()
        self.dealer.display_hand()

        if self.player.hand[0] == self.player.hand[1]:
            hand_result = self.play_hand(self.player.hand, bet)
            if hand_result == 'split':
                split_hand1 = [self.player.hand[0], self.deal_card()]
                split_hand2 = [self.player.hand[1], self.deal_card()]

                print("Playing first split hand:")
                self.player.hand = split_hand1
                result1, bet1 = self.play_hand(self.player.hand, bet)

                print("Playing second split hand:")
                self.player.hand = split_hand2
                result2, bet2 = self.play_hand(self.player.hand, bet)

                self.player.balance -= bet  # Deduct additional bet for split
                player_hands = [result1, result2]
                bets = [bet, bet]  # Each split hand has the same initial bet
            else:
                player_hands = [hand_result[0]]
                bets = [hand_result[1]]
                self.player_hand_visible = True
        else:
            hand_result = self.play_hand(self.player.hand, bet)
            player_hands = [hand_result[0]]
            bets = [hand_result[1]]
            self.player_hand_visible = True

        # Dealer turn
        while self.dealer.calculate_score() < 17:
            self.dealer.receive_card(self.deal_card())

        self.dealer.display_hand(show_all=True)

        # Determine the winner for each hand
        dealer_score = self.dealer.calculate_score()

        for idx, (hand, bet) in enumerate(zip(player_hands, bets)):
            print(f"Evaluating hand {idx + 1}:")
            player_score = self.player.calculate_score()

            if player_score > 21:
                print("Player busts! Dealer wins.")
                self.player.balance -= bet
            elif dealer_score > 21:
                print("Dealer busts! Player wins.")
                self.player.balance += bet
            elif player_score > dealer_score:
                print("Player wins!")
                self.player.balance += bet
            elif dealer_score > player_score:
                print("Dealer wins!")
                self.player.balance -= bet
            else:
                print("It's a tie!")

        if self.player.balance <= 0:
            print("You have run out of money. Game over.")
            break

        play_again = input("Do you want to play another round? (y/n): ").lower()
        if play_again != 'y':
            break

        self.player_hand_visible = False  # Reset player hand visibility for the next round

    print(f"Game over! Your final balance is: ${self.player.balance}")
Enter fullscreen mode Exit fullscreen mode

if name == "main":
player_name = input("Enter your name: ")
game = BlackjackGame(player_name)
game.play()

Top comments (0)