Black Jack Game In Python
Disclaimer: This post is not about gambling but about fun coding exercise to learn Python.
While learning any programing language, it is helpful if we use everything we learnt in a project to demonstrate our learning. One of the best project is to create small games. I though of Black Jack as this is one of the game where skill matters (In card counting).
The rules of this game is as follows:
- Beat the dealer hand without going over 21.
- Ace card represent 1 or 11 to make a better hand.
- Face cards represent value of 10. Rest of the cards represent the number mentioned.
- Hit means asking another card. Stand means to hold your current cards.
- If anyone goes above 21, then they bust.
- If you got 21 you bust, no matter what dealer gets.
- If total of first 2 cards is 21, it’s a BLACKJACK.
- Dealer needs to hit till he gets 17 or above.
- If your card total and the dealer’s total is same, it’s a tie or Push.
That being said, we will begin the game in following manner.
Step 1: Import and Global Variables.
import random as r
from os import system
global num_of_decks
suits_dict = {'S': '\u2660', # Suits
'C': '\u2663', # Club
'H': '\u2665', # Heart
'D': '\u2666', # Diamond
'?': '?'} # Hidden card
Step 2: Creating a Card Class
Card class will be used to initialize the playing deck. As Blackjack can be played with one deck or multiple deck, this class will initiate with the number of deck selected by the user.
class Cards:
def __init__(self, nod):
# The Card Value
rank = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'A', 'J', 'Q', 'K']
# Type of Suit
suits = ['S', 'C', 'H', 'D']
# Creating a single deck
self.deck = ([(idx, jdx) for idx in suits for jdx in rank])
# Creating the number of deck as per user choice
self.deck = self.deck * nod
# Shuffle the deck
r.shuffle (self.deck)
def reshuffle_deck(self, nod):
input ("Deck about to finish. Reshuffling deck. Press any key to continue..")
self.__init__ (nod)
Step 3: Create a hand Class
Hand class will be used to hold the cards either by dealer or by the player. This will also hold the current chip balance, amount of chip betted by the player and whether the player won or lost. This Class will have multiple functions, each to be implemented on the hands deck.
Initial functions
class Hands:
def __init__(self, player_onhand=pow (2, 25), is_dealer=False):
# if this is a dealer hand
self.dealer_hand = is_dealer
# if this hand contains Ace card or total going above 21 for Ace card
self.ace = False
self.cards = []
self.value = 0
self.player_current_balance = player_onhand
self.bet = 0
def win_bet(self):
self.player_current_balance += self.bet
def lose_bet(self):
self.player_current_balance -= self.bet
Step 4: Add a function to deal card
This function will take the last card out from the deck and add that card to the dealer or player hand. Also it will handle the Ace scenarios.
def add_card(self, card):
self.cards.append (card)
if card[1] == 'A':
if not self.ace and (self.value + 11 <= 21):
self.value = self.value + 11
self.ace = True
else:
self.value = self.value + 1
else:
if type (card[1]) == int:
self.value = self.value + card[1]
else:
self.value = self.value + 10
if self.value > 21 and self.ace:
self.value -= 10
self.ace = False
Step 5: Add function to design card
This function will design the card on the screen and it can be used to print each individual card.
def print_card(self, card_suit, pos=1):
s = ""
for _ in card_suit:
s = s + "\t ________"
print (s.rjust (pos))
s = ""
for idx, jdx in card_suit:
if jdx == 10:
s = s + "\t| {0} |".format (jdx)
else:
s = s + "\t| {0} |".format (jdx)
print (s.rjust (pos))
s = ""
for _ in card_suit:
s = s + "\t| |"
print (s.rjust (pos))
s = ""
for idx, jdx in card_suit:
s = s + "\t| {0} |".format (suits_dict[idx])
print (s.rjust (pos))
s = ""
for _ in card_suit:
s = s + "\t| |"
print (s.rjust (pos))
s = ""
for idx, jdx in card_suit:
if jdx == 10:
s = s + "\t| {0} |".format (jdx)
else:
s = s + "\t| {0} |".format (jdx)
print (s.rjust (pos))
s = ""
for _ in card_suit:
s = s + "\t|________|"
print (s.rjust (pos))
Step 6: Function to Display the hand
This function can be used to display the current hand of the player or dealer.
def show_card(self, hide=False):
if self.dealer_hand:
if hide:
print ('Dealer'.rjust (60))
self.print_card ([self.cards[0], ('?', '?')])
else:
print ('Dealer (Total: {0})'.format (self.value).rjust (60))
self.print_card (self.cards)
for idx in range (4): print ('')
else:
print ('Player (Total: {0})'.format (self.value).rjust (60))
self.print_card (self.cards)
print ('Bet Amount: {0}'.format (self.bet).rjust (60))
Step 7: Standalone function to Validate number
Validate whether the user is entering a number or a character.
def validate_number(p_text):
while True:
try:
p_num = int (input (p_text))
except ValueError:
print ("Sorry, please enter a number")
else:
return p_num
Step 8: Standalone function to take the bet
Create a function so that at the beginning of each game, player can place a bet.
def take_bet(player_hand):
while True:
player_hand.bet = validate_number ('How many chips you want to bet: ')
if player_hand.bet > player_hand.player_current_balance:
print ("Sorry, you cannot bet more than {0}".format (player_hand.player_current_balance))
else:
clear_screen ()
break
Step 9: Select the number of deck player wants to play with
def select_play_deck():
global num_of_decks
print ("How may decks you want to play with \n")
num_of_decks = validate_number ("Choose from number 1 to 4: ")
while num_of_decks not in range (1, 5):
clear_screen ()
num_of_decks = int (input ("Invalid Selection. Please select from number 1 to 4: "))
clear_screen ()
Step 10: Start the Game.
We will begin the game by asking the player to select the number of decks he wants to play with. This value will be used till the end of the game and every time we shuffle the cards, we are going to use this value.
print ('Welcome to Black Jack'.rjust (70))
# Asking the player to select the number of decks he would like to play with
select_play_deck ()
# Setting up the deck as per the user choice
card = Cards (num_of_decks)# Setting up player opening balance to 100
player_opening_balance = 100
# Setting up the game flag to Y to start the game.
play = 'Y'
From here we will play the game in a while loop till the time value of variable play is ‘Y’. At the end of each game, system will give a choice to the player to choose whether he wants to continue playing or not.
We will start with a empty dealer hand and player hand and will take the bet from the player.
# Setting up Dealer hand
dealer = Hands (is_dealer=True)
# Setting up player hand with the number of chips he brought to table or he had after the last round
player = Hands (player_opening_balance)
# Taking bet from the player
take_bet (player)
Once the empty hand of the player and dealer is done, we will deal them the cards and then display there cards.
# Dealing initial 2 cards each to player and dealer
for idx in range (2):
player.add_card (card.deck.pop ())
dealer.add_card (card.deck.pop ())
# Displaying dealer Card
dealer.show_card (True)
# Displaying Player Card
player.show_card ()
If the total is less than 22, game will ask the player whether they want to hit or stay. If the user select Hit, program will deal another card and repeat the above cycle. If the user select Stay, then program will move to Dealer hand.
At any given point if the value of player cards goes beyond 21 then game will end and declare the dealer winner.
If the player card values goes to 21, then it will put a stay on player hand and will move to dealer hand.
Once the player hand is dealt, program will deal/add a card to dealer hand and will continue till the time dealer either hits 17 or above or gets busted.
At the end of the each game, it will display the number of chips player has and will ask the player if he wants to play further.
This is my first major project in a new language and would try to keep improving this project to make it a GUI based game in Python.