Section 11: Milestone Project #2

  Python Bootcamp 0 to Hero

< Section 10 | Section 12 >

Overview – Blackjack

https://www.udemy.com/complete-python-bootcamp/learn/lecture/9497646#questions

Instructions

  • Use OOP to create a BlackJack game with Python
  • Computer dealer, human player
  • Normal deck of cards
  • Human:
    • bank amount
  • Dealer 1 up, 1 down
  • Human 2 up
  • Human goes first
    • Hit or stay
      • No splits, Insurance or Double Down
    • Plays until done or bust.
  • If not BUST, computer plays until they beat the Human (WHAT?)
  • Special Rules
    • Face cards = 10
    • Aces are 11 or 1 depending on requirement

My Solution

Not as eloquent, but far more flexible and realistic.

blackjack.py

from blkjkc import *

def get_players():
    while True:
        try:
            players = int(input("Enter the number of players (1 - 7): "))
        except:
            print("Invalid number entered. Please try again.")
            continue
        else:
            if players < 1 or players > 7:
                print("Invalid number entered. Please try again.")
                continue
            else:
                break
    return players

#get players
player=[]
numplayers = get_players()
for i in range(0, numplayers+1):
    # print(i)
    player.append(Player(i))

# Start game
game_on = True
while game_on:
    # get new deck
    print("Shuffling new deck...")
    deck = Deck()
    # Get bets
    for player_num in range(1,numplayers+1):
        player[player_num].get_bet()
    #deal the first 2 cards
    for i in range(0,2):
        for player_num in range(0,numplayers+1):
            if player[player_num].bet:
                card = deck.get_card()
                #print(f"Card is {card}")
                player[player_num].hit(card)

    #show everyone's hand
    print("\nHere are your cards...")
    for player_num in range(0,numplayers+1):
        if player[player_num].bet:
            hand=player[player_num].hand.show(player_num)
            if player_num:
                #not the dealer
                tally = player[player_num].hand.tally()
            else:
                tally='??'
            print(player[player_num].name + f" ({tally}): "+ hand)
            if tally == 21:
                print(f"Black Jack!  You won ${player[player_num].bet}")
                player[player_num].bank += player[player_num].bet ** 2
                player[player_num].bet = 0
    #Start Play!
    for player_num in range(1,numplayers+1):
        if player[player_num].bet:
            print(player[player_num].name)
            while True:
                print("You have "+ str(player[player_num].hand.tally()))
                hit=input("Hit or Stay (h / S)")
                if hit.lower() != 'h' and hit.lower() != 'hit' :
                    break
                #Hit
                card = deck.get_card()
                player[player_num].hit(card)
                print(f"Your new card is: {card}")
                tally = player[player_num].hand.tally()
                if tally >= 21:
                    break
            if player[player_num].hand.tally() > 21:
                print("BUST!")
                player[player_num].bet=0
    #Dealer's turn
    hand=player[0].hand.show()
    tally = player[0].hand.tally()
    print(f"Dealer ({tally}): " + hand)
    while player[0].hand.tally()<17:
        card = deck.get_card()
        player[0].hit(card) 
    print(f"Dealer takes a: {card}") 
    #check for winners 
    dealer_tally = player[0].hand.tally()
    if dealer_tally >21:
        print("Dealer Busts!")
    else:
        print(f"Dealer stands on {dealer_tally}")
    for player_num in range(1,numplayers+1):
        if player[player_num].bet:
            if player[player_num].hand.tally()>dealer_tally or dealer_tally>21:
                player[player_num].bank += player[player_num].bet * 2
                print(f"\n{player[player_num].name} won ${player[player_num].bet}!")
                print(f"You now have ${player[player_num].bank}")
            elif player[player_num].hand.tally()==dealer_tally:
                player[player_num].bank += player[player_num].bet
                print(f"\n{player[player_num].name} tied!")
            else:
                print(f"\n{player[player_num].name} lost!")
                print(f"You still have ${player[player_num].bank} left in your account.")
    play=input("\nPlay again? (Y / n)")
    if play.lower() == 'n' or play.lower() == 'no':
        game_on = False
    else:
        # reset player's hands
        for player_num in range(0, numplayers+1):
            player[player_num].reset()
print("\nThanks for playing!")

blkjkc.py

import random
class Card():
    def __init__(self, suit, face, value):
        self.suit = suit
        self.face = face
        self.value = value
        if suit == 'H' or suit == 'D':
            self.color = 'red'
        else:
            self.color = 'black'
    def __str__(self):
        return self.face + self.suit
    def show(self, hole_card=False):
        if not hole_card:
            return self.face + self.suit
        else:
            return 'XX'

class Deck():
    def __init__(self, decks=1):
        self.deck=[]
        try:
            decks = int(decks)
        except:
            decks = 1
        for deck in range(0,decks):
            for suit in ['H', 'C', 'S', 'D']:
                # 2 - 10
                for face in range(2, 11):
                    self.deck.append(Card(suit, str(face), face))
                # Face cards
                for face in ['K', 'Q', 'J']:
                    #card = Card(suit, face, 10)
                    self.deck.append(Card(suit, face, 10))
                # Aces
                self.deck.append(Card(suit, 'A', 11))
        random.shuffle(self.deck)
    def __len__(self):
        return len(self.deck)
    def __str__(self):
        cards=[]
        for card in self.deck:
            cards.append(card.show())
        return str(cards)
    def get_card(self):
        if (len(self.deck))>=1:
            return self.deck.pop()
        return False

class Hand():
    def __init__(self):
        self.cards=[]
    def hit(self, card):
        self.cards.append(card)
        return self.tally()
    def show(self, show_hole=True):
        firstcard=True
        cards = []
        for card in self.cards:
            if firstcard:
                firstcard = False
                cards.append(card.show(not show_hole))
            else:
                cards.append(card.show())
        return " | ".join(cards)
    def tally(self):
        self.total = 0
        aces=[]
        for card in self.cards:
            self.total += card.value
        if self.total > 21:
            # Look for aces
            for card in self.cards:
                if card.face == 'A':
                    self.total -= 10
                    if self.total <=21:
                        # Stop looking for aces
                        break
        return self.total
class Player():
    def __init__(self, player_num):
        self.hand = Hand()
        if not player_num:
            #is dealer
            self.name = 'Dealer'
            self.bet = True
        else:
            #Get name
            while True:
                self.name = input(f"\nPlayer #{player_num}, please enter your name: ")
                if len(self.name.strip()):
                    break
                else:
                    self.name = "Sofia"
                    break
                    #print("Invalid name enterd. Please try again.\n")
            while True:
                try:
                    self.bank=int(input(f"Hello {self.name}. How much money did you bring? $"))
                except:
                    self.bank = 10
                    break
                    #print("Invalid amount enterd. Please try again.\n")
                    #continue
                else:
                    if self.bank <= 0: 
                        self.bank = 0
                        print(f"I'm sorry, {self.name}. That is not enough money to play, but you may stay and watch.")
                        break 
    def get_bet(self):
        if self.bank > 0:
            while True:
                try:
                    self.bet=int(input(f"{self.name}. How much do you wish to bet? (Max {self.bank}) $"))
                except:
                    self.bet = 1
                    break
                    #print("Invalid amount enterd. Please try again.\n")
                    #continue
                else:
                    self.bet=abs(self.bet)
                    if self.bet >= self.bank:
                        self.bet = self.bank
                    self.bank -= self.bet
                    if self.bet==0:
                        print("OK. Please stay and watch.")
                    break
        else:
            self.bet = 0
            print(f"I'm sorry, {self.name}.  You do not have enough money to play, but you may stay and watch.")
        return self.bet
    def hit(self, card):
        self.hand.hit(card)
    def reset(self):
        self.hand = Hand()

 

LEAVE A COMMENT