# Blackjack console game using Python

In this tutorial, let’s explore how to code a console playable blackjack game using Python with an easy approach to understand the flow of the game.

Blackjack is a simple cards game it requires a deck of 52 cards.

Importing the necessary Python modules

```import random  # random module for picking a random card from the deck
from itertools import product  # to avoid nested for loops lets import product from itertools module
import math  # to use absolute function from the math module

# let us declare 2 global variables innerplay and outerplay for regulating the game conditions here.
outerplay = ""
innerplay = ""
# these global variables are used within a function to a make changes at a global scope and to avoid error these must be declared before usage```

## Generating a deck of cards:

Lets create a list of all the of all the 4 suits in a card and a list of all the cards in each suit, along with a dictionary consisting of each card with its value.

Here Ace is mapped to a  score of 11 however this is will be later decided as per the needs of the particular round in game because an Ace is either a score of 11 or 1 in Blackjack depending on whichever is best.

```suit = ['clubs', ' spades', 'diamonds', 'hearts']
value_cards = {
'Four': 4,
'Two': 2,
'Three': 3,
'Five': 5,
'Six': 6,
'Seven': 7,
'Eight': 8,
'Nine': 9,
'Ten': 10,
'Jack': 10,
'Queen': 10,
'King': 10,
'Ace': 11
}
face_cards = ['king', 'queen', 'jack', 'ace', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']```

Lets create card class that generates a deck of cards. So that each object of this class generates an individual deck of 52 cards. This class generates a deck of 52 cards and it has method to pop one card from the shuffled deck.

```class CardGen():
def __init__(self):
self.face_cards = face_cards
self.suit = suit
self.deck = []
for suite, rankie in product(self.suit, self.face_cards):
self.deck.append((rankie, suite))

def cardsrandom(self):
random.shuffle(self.deck)  # randomly shuffling the deck
f1, s1 = self.deck.pop()
return f1, s1```

Creating a money class to keep account of the players winnings and losings in a game:

```class money():
def __init__(self, chips):
self.chips = chips
self.wincase = 1.5  # a gain of 50 % on his bettings

def wincasecalc(self, bet):  # method to be called when player wins to add his winnings to his account
if bet <= self.chips:
self.chips = self.chips + bet * self.wincase
print(f'You are now left with {self.chips}\n')
print(f'You have gained an additional of {bet * self.wincase}\n')

def loosecase(self, bet):  # method to be called when player loses to deduct his loss from his acoount
if bet <= self.chips:
self.chips = self.chips - bet
print(f'You are now left with {self.chips}\n')
print(f'You lost an amount of {bet}\n')```

### Creating all the necessary functions for the flow of this game:

• Card display function: It takes in the rank and suit of the card and prints it as “rank of suit”.
• Hit or stand function: The dealer by default hits until his score is 17 this function is primarily aimed at the players choice of whether he would like another card or stand his ground.
• Bet taking function: It ensures that player is able to bet an amount that is greater than equal to his balance in account.
• Score calculating function: This function calculates the score, in case of an Ace card it calculates 2 scores with one score where ace is valued as 1 and another score where ace is valued as 11 and the score that is closest to winning condition of the game will be selected based on their turn.
• Win check function: This function will be repeatedly called to check who among the player and the dealer has won the game. All cases to decide the result of the game have been considered here.
• Play again function: This function is to ask the player if they would like to play another game.
```def carddisplay(ts1, tf1):  # Card dusplay function
print(f' {tf1} of {ts1} ')

def bettake(amount):  # Bet taking function
betting_amount = int(input('How much would you like to bet?\n'))
if amount < betting_amount:
print(f'Sorry your betting amount exceeds your balance! You currently have a balance of {amount}\n')
bettake(amount)  # recurrent function until the condition is satisfied
return betting_amount
else:
return betting_amount

def scorecalculator(currentcard, score=0):   # function that takes the input of current card and score to return the updated score
if currentcard == 'ACE':
score1 = score + 11   # score calcuated with ace valued as 11
score2 = score + 1   # score calculated with ace valued as 1
if math.fabs(21 - score1) < math.fabs(21 - score2):    # the score closest to 21 is returned
return score1
else:
return score2
else:
score = score + value_cards.get(currentcard.capitalize(), 0)
return score

def wincheck(playerscore, dealerscore, balance, bettin_gamount):   # function that compares current score of player and dealer and checks win/lose case and makes appropriate actions on the players account
if playerscore > 21:   # checks if player score is above 21, then player loses
print('Player bust!\n')
print('You have lost the game!\n')
print(f'Your score:{playerscore}, and dealers score : {dealerscore}\n')
balance.loosecase(bettin_gamount)
return 'LOST'
elif dealerscore > 21:   # check is dealer score is above 21, then dealer loses
print('You have won!\n')
print(f'Your score:{playerscore}, and dealers score : {dealerscore}\n')
balance.wincasecalc(bettin_gamount)
return 'WON'

elif playerscore == 21:
if dealerscore ==21:  # if players score and dealers score both are equal then its a tie
print('ITS A TIE!\n')
print(f'balance{balance.chips}\n')
return 'TIE'
else:
print('Player wins!\n')  # if players score is 21 then player wins
print('You have won the game!\n')
print(f'Your score:{playerscore}, and dealers score : {dealerscore}\n')
balance.wincasecalc(bettin_gamount)
return 'WON'
elif dealerscore == 21:  # if dealer score is 21 then dealer wins
print('Player bust!\n')
print('You have lost the game!\n')
print(f'Your score:{playerscore}, and dealers score : {dealerscore}\n')
balance.loosecase(bettin_gamount)
return 'LOST'
elif playerscore < 21 and 21 > dealerscore >= 17:
if playerscore > dealerscore:   # if players score is close to 21 then player wins
print('Player wins!\n')
print('You have won the game!\n')
print(f'Your score:{playerscore}, and dealers score : {dealerscore}\n')
balance.wincasecalc(bettin_gamount)
return 'WON'
elif dealerscore > playerscore:  # else if dealers score is close to 21 then dealer wins
print('Player bust!\n')
print('You have lost the game!\n')
print(f'Your score:{playerscore}, and dealers score : {dealerscore}\n')
balance.loosecase(bettin_gamount)
return 'LOST'

def hitorstand(turns, dscore, playercards, dealercards):   # players choice as to whether he would like to hit or stand
if turns == 'PLAYER':  # checking if it is players turn
choice = input('Would you like to hit or stand?').upper()
if choice == 'HIT':
pf, ps = playercards.cardsrandom()
return ps, pf
elif choice == 'STAND':
return 0, 0

elif turns == 'DEALER':  # checking dealers turn
if dscore <= 17:   # dealer hits by default if the score is less than equal to 17
print('DEALERS CARD:')
df, ds = dealercards.cardsrandom()
return ds, df
else:
print('As per the rules dealer chooses to stand!')
return 0, 0

def playagain(replaychoice):   # function to recreate game conditions if the player wishes to play again
global innerplay
global outerplay
if replaychoice == 'Y':
innerplay = False
elif replaychoice == 'N':
outerplay = 'n'
innerplay = False
print('Thank you for playing have a great day!\n')

```

Now initiating the game play loop using the functions that we defined above:

```# MAIN GAME BEGINS HERE INNERPLAY AND OUTERPLAY LOOPS ARE TO REGULATE GAME PLAY FOR REPLAY AND EXIT LOOP.

print('HELLO WELCOME TO BLACK JACK GAME!')
outerplay = input('Ready to play, type y for yes n for no\n').upper()  # beginning the outer loop of the game
while outerplay == 'Y':
amount = int(input('What amount would you want in chips?\n'))  # taking user input for account
Balance = money(amount)  # creating players account using the defined money class
print('Let the game begin, dealer hits\n')
turn = 'PLAYER'  # initiating the first turn of player
pscore = 0  # initial score of the player
dscore = 0  # initial score of the dealer
playercards = CardGen()  # generating a deck of cards for player
dealercards = CardGen()  # generating a deck of cards for dealer
df1, ds1 = dealercards.cardsrandom()  # popping a random card from players deck
df2, ds2 = dealercards.cardsrandom()  # popping a random card from dealers deck
print('DEALERS CARD:\n')
print('<card hidden>')
carddisplay(ds2, df2)  # displaying one of dealers card
dscore = scorecalculator(df2, dscore)  # updating dealers score
pf1, ps1 = playercards.cardsrandom()  # generating 2 random cards of player
pf2, ps2 = playercards.cardsrandom()

carddisplay(ps1, pf1)  # displaying both player cards
carddisplay(ps2, pf2)
bettingmoney = bettake(amount)  # taking an appropriate bet amount
pscore = scorecalculator(pf1, pscore)  # updating players score
pscore = scorecalculator(pf2, pscore)

print('DEALERS CARDS:')
carddisplay(ds1, df1)
carddisplay(ds2, df2)
dscore = scorecalculator(df1, dscore)
# checking game status of whether the player or dealer has won
currentstatus = wincheck(pscore, dscore, Balance, bettingmoney)
if currentstatus == 'WON' or currentstatus == 'LOST' or currentstatus == 'TIE':
break  # if player or dealer has won then exit the outerplay loop
innerplay = True
turn = 'PLAYER'   # changing turn to players turn
while innerplay:   # an inner loop for the game to progress until one of them loses or wins
if turn == 'PLAYER':
ps, pf = hitorstand('PLAYER', dscore, playercards, dealercards)   # whether players wishes to hit or stand
if pf == 0:
turn = 'DEALER'  # changing it to players turn
else:
carddisplay(ps, pf)
pscore = scorecalculator(pf, pscore)
currentstatus = wincheck(pscore, dscore, Balance, bettingmoney)
if currentstatus == 'WON' or currentstatus == 'LOST' or currentstatus == 'TIE':
break
turn = 'DEALER'
elif turn == 'DEALER':
ds, df = hitorstand('DEALER', dscore, playercards, dealercards)
if df == 0:
turn = 'PLAYER'
else:
carddisplay(ds, df)
dscore = scorecalculator(df, dscore)
currentstatus = wincheck(pscore, dscore, Balance, bettingmoney)
if currentstatus == 'WON' or currentstatus == 'LOST' or currentstatus == 'TIE':
break
turn = 'PLAYER'
replaychoice = input('Would you like to play again? Y for yes and N for no.').upper()
playagain(replaychoice)   # taking players input if they wish to play again from the start
rating = input('How  would you like to rate this game play out of 5?\n')
print(rating)
print('THANK YOU!\n')```

### Output:

```HELLO WELCOME TO BLACK JACK GAME!
Ready to play, type y for yes n for no
y
What amount would u want in chips?2000
Let the game begin, dealer hits
DEALERS CARD:

<card hidden>
two of clubs

ten of diamonds
How much would you like to bet?
500
DEALERS CARDS:
eight of diamonds
two of clubs
would you like to hit or stand?
stand
DEALERS CARD:
three of diamonds
Would you like to hit or stand?stand
DEALERS CARD:
Player wins!

You have won the game!

Your score:19, and dealers score : 18
You are now left with 2750.0

You have gained an additional of 250.0

Would you like to play again? Y for yes and N for no.n
Thank you for playing have a great day!

How would you like to rate this game play out of 5?4
4
THANK YOU!```
• This game can be coded with a minimalist approach in few lines of code. However the aim here is to have an understanding of  how to approach such problem statements.