# Simple Blackjack game in Python

I am trying to create a simple Blackjack game. I am using GIST because the code sample takes forever to use.

Current code:

from random import randint
def card_deck():
#sets the card types and values
card_value = ['Ace','2','3','4','5','6','7','8','9','10','J','Q','K']
deck = []
#This iterates all 52 cards into a deck
for i in card_type:
for j in card_value:
deck.append(j + ' of ' + i)
return deck

def card_value(card):
#only reading first slice to determine value of the card
if card[:1] in ('J','Q','K','1'):
return int(10)
elif card[:1] in ('2','3','4','5','6','7','8','9'):
#card[:1] example '2' out of the full '2 of Hearts' string
return int(card[:1])
elif card[:1] == 'A':
print ("\n"+ str(card))
num = input("Do you want this to be 1 or 11?\n>")
while num !='1' or num !='11':
if num == '1':
return int(1)
elif num == '11':
return int(11)
else:
num = input("Do you want this to be 1 or 11?\n>")

def new_card(deck):
return deck[randint(0,len(deck)-1)]

def remove_card(deck,card):
return deck.remove(card)

play_again = ''
while play_again != 'EXIT':
#deck creation, card creation, card removal from deck, values and totals
new_deck = card_deck()
card1 = new_card(new_deck)
remove_card(new_deck,card1)
card2 = new_card(new_deck)
remove_card(new_deck,card2)
print ("\n\n\n\n" + card1 + " and " + card2) #doing this statement first allows for selection between 1 and 11
valu1 = card_value(card1)
valu2 = card_value(card2)
total = valu1 + valu2
print("with a total of " + str(total) )

#dealer's hand
dealer_card1 = new_card(new_deck)
remove_card(new_deck,dealer_card1)
dealer_card2 = new_card(new_deck)
remove_card(new_deck,dealer_card2)
dealer_value1 = card_value(dealer_card1)
dealer_value2 = card_value(dealer_card1)
dealer_total = dealer_value1 + dealer_value2
print ('\nThe Dealer smiles as he looks at you and\n deals one card up and one card face down')
print ("First a " + dealer_card1 + " and face down card.")

if total == 21:
print("Blackjack!")
else:
while total < 21: #not win or loss yet
answer = input("Would you like to hit or stand?\n> ")
#more card creation, removal, and value added to total
more_card = new_card(new_deck)
remove_card(new_deck,more_card)
more_value = card_value(more_card)
total += int(more_value)
print (more_card + " for a new total of " + str(total))
if total > 21: #lose condition
print("You LOSE!")
play_again = input("Would you like to continue? EXIT to leave\n")
elif total == 21: #winning condition
print("You WIN BIG WIN WOO WOO")
play_again = input("Would you like to continue? EXIT to leave\n")
else:
continue
print("The dealer nods and reveals his other card to be ")
print("a " + dealer_card2 + " for a total of " + str(dealer_total))
if dealer_total < 17:
print("The Dealer hits again.")
dealer_more = new_card(new_deck)
more_dealer_value = card_value(dealer_more)
print("The card is a " + str(dealer_more))
dealer_total += int(more_dealer_value)
if dealer_total > 21 and total <=21:
print("Dealer Bust! You win!")
elif dealer_total < 21 and dealer_total > total:
print("Dealer has " + str(dealer_total) + " You lose!")
else:
continue
elif dealer_total == total:
print("Equal Deals, no winner")
elif dealer_total < total:
print("You win!")
else:
print("You Lose!")
play_again = input("\nWould you like to continue? EXIT to leave\n")
break
print("Thank you for Playing")


New (is my Blackjack program code so far using classes):

from random import randint

class Card:
def __init__(self):
pass

def card_value(self):
pass

card_face = ['Ace','2','3','4','5','6','7','8','9','10','J','Q','K']

class Deck(Card):
new_deck = []
length = len(new_deck) #testing purposes

for i in Card.card_suit:
for j in Card.card_face:
new_deck.append(j + ' of ' + i)

def new_card(self):
return (self.new_deck[randint(0,len(self.new_deck)-1)])
def remove_card(self,card):
self.new_deck.remove(card)

deck1 = Deck()
card1 = deck1.new_card()
deck1.remove_card(card1)
card2 = deck1.new_card()
deck1.remove_card(card2)
print(str(card1) + " and " + str(card2))
print(len(deck1.new_deck))


I am looking for beginner advice on how or where to start with my process on fleshing out my functions/code into classes. My original code does work for what it does, but I feel that it has too much manual code and I would like some tips/advice on where to go from here.

• okay I fixed it Dec 14, 2016 at 15:51
• do you want us to review your code(which is not finished yet) or just help you build skeleton(help to find right approach) of your game?
– Alex
Dec 14, 2016 at 16:08
• help to find the right approach would be great or if you notice anything that I definitely should not be doing, that would be good to point out as well :) Dec 14, 2016 at 16:18
• I think you really need to read the documentation on how classes in python work. For example, you would rarely ever have free standing code as seen in the Deck class, you would either put it in the __init__ function or under a different function Dec 14, 2016 at 18:26
• So does this mean you couldn't use classes for this at all? Dec 14, 2016 at 18:42

Let's look at your Card class.

class Card:
def __init__(self):
pass

def card_value(self):
pass

card_face = ['Ace','2','3','4','5','6','7','8','9','10','J','Q','K']


There are multiple design mistakes.

1. Card should not evaluate it's value, since a value of card defined by the game. Basically, if you would like to reuse this class for say Poker you would have to create a child class for the Card just to evaluate its value for a different game, which is wrong.

2. In your case, Card class knows about suits and ranks, which is also in my opinion wrong solution, since you might use any other deck except for French.

So as a result of first 2 problems, it turns out that your Card is just a container(structure) without any logics inside, one of the best things to use for that in python in namedtuple

from collections import namedtuple
Card = namedtuple('Card', ('rank', 'suit'))


Now let's talk about Deck

class Deck(Card):
new_deck = []
length = len(new_deck) #testing purposes

for i in Card.card_suit:
for j in Card.card_face:
new_deck.append(j + ' of ' + i)

def new_card(self):
return (self.new_deck[randint(0,len(self.new_deck)-1)])
def remove_card(self,card):
self.new_deck.remove(card)


1. Deck is definitely not a Card child, Deck is sort of collection of cards.

2. Your new_card and remove_card methods should be combined into single one called draw_card.

3. Since now we know that Deck is not a Card then the most right place to keep track of ranks and suits is Deck. Here is example:

class Deck:
card_ranks = []
card_suits = []

def __init__(self):
self.cards = []
self.refresh_deck()

def refresh_deck(self):
self.cards = list(map(Card, product(self.card_ranks, self.card_suits)))

def shuffle(self):
shuffle(self.cards)

def draw_card(self):
return self.cards.pop()


Game class

Now things like play_game, card_value(hand_value?) and other things/rules related to specific game should be defined by Game class

class Game:
def __init__(self, deck):
raise NotImplementedError

def card_value(self, card):
raise NotImplementedError

def hand_value(self, hand):
raise NotImplementedError

def play(self):
raise NotImplementedError


So in the end what we have as a game skeleton is this:

from collections import namedtuple
from itertools import product
from random import shuffle
from typing import List

Card = namedtuple('Card', ('rank', 'suit'))

class Deck:
card_ranks = []
card_suits = []

def __init__(self) -> None:
self.cards = []
self.refresh_deck()

def refresh_deck(self) -> int:
self.cards = map(Card, product(self.card_ranks, self.card_suits))

def shuffle(self) -> None:
shuffle(self.cards)

def draw_card(self) -> Card:
return self.cards.pop()

class FrenchDeck(Deck):
card_ranks = ['Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
card_suits = ['Hearts', 'Spades', 'Clubs', 'Diamonds']

class Game:
def __init__(self, deck: Deck) -> None:
raise NotImplementedError

def card_value(self, card: Card) -> int:
raise NotImplementedError

def hand_value(self, hand: List[Card]) -> int:
raise NotImplementedError

def play(self) -> None:
raise NotImplementedError

• Sorry I havent had a chance to respond to this, the internet connection from my home was down~ This will give me some wonderful tips and a skeleton to look at and work off of, thank you so much! Dec 17, 2016 at 12:27

When you "stand" it tells you the dealers other card, then he hits/stands, then you get to hit or stand, that's not blackjack, you need to take out the other hit/stand after the dealer reveals his/her hand.