Skip to the content.

Blackjack Game for sprint 2

This uses elif statemnts, booleans, classes, and other new things I learned

import random

class Card:
    def __init__(self, rank, suit):
        # Initialize a card with a rank and a suit
        self.rank = rank
        self.suit = suit
    
    def value(self):
        # Return the value of the card: 10 for face cards, 11 for Ace, or the numeric value for others
        if self.rank in ['J', 'Q', 'K']:
            return 10
        elif self.rank == 'A':
            return 11
        else:
            return int(self.rank)
    
    def __str__(self):
        # Return a string representation of the card (e.g., "10 of Hearts")
        return f"{self.rank} of {self.suit}"

class Deck:
    def __init__(self):
        # Create a deck of 52 cards and shuffle them
        ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
        suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
        self.cards = [Card(rank, suit) for rank in ranks for suit in suits]
        random.shuffle(self.cards)  # Shuffle the cards for randomness

    def draw_card(self):
        # Remove and return the top card from the deck
        return self.cards.pop()

class BlackjackHand:
    def __init__(self):
        # Initialize an empty hand for a player or dealer
        self.cards = []

    def add_card(self, card):
        # Add a card to the hand
        self.cards.append(card)

    def total(self):
        # Calculate the total value of the hand, adjusting for Aces if necessary
        total_value = sum(card.value() for card in self.cards)
        num_aces = sum(1 for card in self.cards if card.rank == 'A')
        
        # Adjust for Aces: if total is over 21, count Aces as 1 instead of 11
        while total_value > 21 and num_aces > 0:
            total_value -= 10
            num_aces -= 1
        
        return total_value  # Return the calculated total value

    def __str__(self):
        # Return a string representation of the hand
        return ', '.join(str(card) for card in self.cards)

class BlackjackGame:
    def __init__(self):
        # Initialize the game with a new deck and empty hands for the player and dealer
        self.deck = Deck()
        self.player_hand = BlackjackHand()
        self.dealer_hand = BlackjackHand()

    def deal_initial_cards(self):
        # Deal two cards to the player and two cards to the dealer
        self.player_hand.add_card(self.deck.draw_card())
        self.player_hand.add_card(self.deck.draw_card())
        self.dealer_hand.add_card(self.deck.draw_card())
        self.dealer_hand.add_card(self.deck.draw_card())

    def play_player_turn(self):
        # Allow the player to take turns until they decide to stand or bust
        while True:
            print(f"Your hand: {self.player_hand} (Total: {self.player_hand.total()})")
            if self.player_hand.total() > 21:
                print("You busted!")  # Player busts if total exceeds 21
                return False
            move = input("Do you want to 'hit' or 'stand'? ").lower()
            if move == 'hit':
                self.player_hand.add_card(self.deck.draw_card())  # Player draws a card
            elif move == 'stand':
                break  # Player ends their turn
            else:
                print("Invalid choice! Type 'hit' or 'stand'.")  # Handle invalid input
        return True

    def play_dealer_turn(self):
        # Dealer's turn: must draw until they reach at least 17
        print(f"Dealer's hand: {self.dealer_hand} (Total: {self.dealer_hand.total()})")
        while self.dealer_hand.total() < 17:
            print("Dealer hits.")
            self.dealer_hand.add_card(self.deck.draw_card())  # Dealer draws a card
            print(f"Dealer's hand: {self.dealer_hand} (Total: {self.dealer_hand.total()})")
        if self.dealer_hand.total() > 21:
            print("Dealer busted!")  # Dealer busts if total exceeds 21
            return False
        return True

    def determine_winner(self):
        # Compare the totals of the player and dealer to determine the winner
        player_total = self.player_hand.total()
        dealer_total = self.dealer_hand.total()
        print(f"Your final hand: {self.player_hand} (Total: {player_total})")
        print(f"Dealer's final hand: {self.dealer_hand} (Total: {dealer_total})")

        # Determine the outcome based on the totals
        if player_total > 21:
            print("You lose!")
        elif dealer_total > 21 or player_total > dealer_total:
            print("You win!")
        elif player_total < dealer_total:
            print("Dealer wins!")
        else:
            print("It's a tie!")

    def play_game(self):
        # Start the game by dealing cards and managing turns
        self.deal_initial_cards()
        if self.play_player_turn():  # Player's turn
            if self.play_dealer_turn():  # Dealer's turn
                self.determine_winner()  # Determine the winner

# Create an instance of the game and start playing
game = BlackjackGame()
game.play_game()


game = BlackjackGame()
game.play_game()
Your hand: 4 of Clubs, 8 of Spades (Total: 12)
Your hand: 4 of Clubs, 8 of Spades, 9 of Clubs (Total: 21)
Your hand: 4 of Clubs, 8 of Spades, 9 of Clubs, K of Clubs (Total: 31)
You busted!
Your hand: A of Clubs, 8 of Spades (Total: 19)
Dealer's hand: J of Diamonds, 6 of Hearts (Total: 16)
Dealer hits.
Dealer's hand: J of Diamonds, 6 of Hearts, 7 of Clubs (Total: 23)
Dealer busted!