Following is my code for a blackjack Game I've written:
Thanks.
Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Visit Stack ExchangeStack Internal
Knowledge at work
Bring the best of human thought and AI automation together at your work.
Explore Stack InternalFollowing is my code for a blackjack Game I've written:
import random
from random import choice
import os
import time
import texttable
class Stack():
def __init__(self, replay, winnings):
self.start_amount = 100
self.stored_bet = 0
self.stored_end = 0
self.replay = replay
if self.replay == 0:
self.stored_end = 0 #needs to be initialized
else:
self.stored_end = self.stored_end + winnings
def load_account(self):
self.stored_end = self.start_amount
def account(self, begin, change):
end = float(begin) + float(change)
self.stored_end = end # store class variable??
return(begin, change, end)
def bet_test(self, miss_type):
# collect's bet and check input
# miss_type should start as 0
possible_bets = ['5', '10', '15', '20', '25']
while True:
print "\nWhat is your bet? (5, 10, 15, 20, 25)"
bet = raw_input(' >')
if bet in possible_bets:
bet = int(bet)
if self.replay == 1:
begin = self.stored_end
self.stored_bet = int(bet)
break
else:
if bet > self.stored_end:
print "You don't have enough for that bet."
time.sleep(2)
else:
begin = self.stored_end
self.stored_bet = bet
break
class DECK():
def __init__(self):
suite = ('Spades', 'Hearts', 'Diamonds', 'Clubs')
rank = ('2', '3', '4', '5', '6', '7', '8', '9', '10', "Jack", "Queen", "King", "Ace")
self.full_deck = {}
n = 0
i = 0
for n in range(6):
for s in suite:
for r in rank:
self.full_deck[i + n] = "%s of %s" % (r, s)
i += 1
n += 1
self.values = {'Ace':11, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'Jack': 10, 'Queen': 10, 'King': 10}
self.test_hand1 = {0: 'Ace of Spades', 1: 'Jack of Clubs' } # for testing
self.test_hand2 = {0: 'Ace of Clubs', 1: '10 of Diamonds' } # for testing
self.test_hand3 = {0: '8 of Spades', 1: '8 of Hearts'} # for testing splits
self.hand_dict = {} # this will be a dict of all the hand instances created by Hand.
self.incomplete_hands = {} # hands yet to be played
self.compltete_hands = {} # hands done being played
# re-split hands and counters
self.split_counter = 0
def hand_table(self):
# show table of hands
hands_dict = {}
bets_dict = {}
points_dict = {}
for hand in Hand.instances:
hands_dict.setdefault(hand.name, hand.hand_a)
bets_dict.setdefault(hand.name, hand.bet)
points_dict.setdefault(hand.name, hand.hand_points)
first_cards = []
second_cards = []
third_cards = []
fourth_cards = []
fifth_cards = []
bets_list = []
points_list = []
for hand in hands_dict:
first_cards.append(hands_dict[hand].get(0))
second_cards.append(hands_dict[hand].get(1))
third_cards.append(hands_dict[hand].get(2))
fourth_cards.append(hands_dict[hand].get(3))
fifth_cards.append(hands_dict[hand].get(4))
bets_list.append("Bet is %r" % bets_dict[hand])
points_list.append("Points are %r" % points_dict[hand])
print "\n"
header = hands_dict.keys()
table = texttable.Texttable()
table.header(header)
table.add_rows([first_cards, second_cards, third_cards, fourth_cards, fifth_cards, points_list, bets_list], header = False)
print table.draw()
def dhos(self):
# dealer hit or stick
os.system("clear")
#show table of hands
self.hand_table()
print " _ " * 10
game.deck.d_hand.show_hand()
time.sleep(1.5)
dpoints, d_raw_points = game.deck.d_hand.points()
if dpoints < 17:
new_card = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
print new_card
hl = len(game.deck.d_hand.hand_a.keys()) # hl is hand length
game.deck.d_hand.hand_a[hl] = new_card # insert new hard into the given hand
self.dhos()
else:
game.deck.d_hand.hand_points = dpoints
game.end_game()
def deal(self):
# deal two cards each to dealer and player
dhand = {}
phand = {}
for i in range (2):
phand[i] = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
dhand[i] = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
# actual hand
# creat instance of Hand for player's starting hand
self.start_hand = Hand(phand, game.deck.full_deck, 0, "Opening Hand")
# start_hand instance is now a member of the deck object.
# creat instance of Hand for dealer's starting hand
self.d_hand = Hand(dhand, game.deck.full_deck, 0, "Dealer")
# d_hand instance is now a member of the deck object.
def split_algo(self, hand):
print hand.hand_a
# old cards
card1 = hand.hand_a[0]
card2 = hand.hand_a[1]
print card1
print card2
# new cards
card_a = self.full_deck.pop(random.choice(self.full_deck.keys()))
card_b = self.full_deck.pop(random.choice(self.full_deck.keys()))
print card_a
print card_b
#two new hands
new_hand_a = {0: card1, 1: card_a}
new_hand_b = {0: card2, 1: card_b}
if game.deck.split_counter == 0:
self.split_1 = Hand(new_hand_a, game.deck.full_deck, 0, 'Split 1')
self.split_2 = Hand(new_hand_b, game.deck.full_deck, 0, 'Split 2')
# load bets: equal to bet on first hand
self.split_1.bet = game.deck.start_hand.bet
self.split_2.bet = game.deck.start_hand.bet
split_hands_dict = {0: self.split_1, 1: self.split_2}
# find the staring hand 'test split' in this case and delete it
for x in range(len(Hand.instances)):
if Hand.instances[x-1].name == 'Opening Hand':
del Hand.instances[x-1]
game.deck.split_counter += 1
return split_hands_dict
class Hand():
instances = [] # used to keep track of hand instances
def __init__(self, hand_a, play_deck, split_count, name): # hand_a for hand actual
Hand.instances.append(self)
self.hand_a = hand_a # the actual hand when instance created
# self.play_deck = play_deck # need to move this to deck class
self.split_count = split_count
self.name = name
self.hand_points = 0
self.raw_points = 0
self.aces = 0
self.testy = self
self.status = 'incomplete'
self.bet = 0
self.stack_change = 0
self.outcome = ''
self.black_jack = 0
def show_hand(self):
print "%r hand is:" % self.name
for i in range(len(self.hand_a.keys())):
print self.hand_a[i]
print "\n"
def show_card(self, key):
return self.hand_a[key]
def points(self):
ln = len(self.hand_a.keys())
tpoints = 0
# add up all the cards with aces = 11
self.aces = 0
for i in range(ln):
card, rank = self.card_and_rank(self.hand_a[i])
# add up all the aces
if rank == 'Ace':
self.aces += 1
# deck is an object of game
tpoints = game.deck.values[rank] + tpoints
raw_points = tpoints
# check to see if there are aces in the hand.
if self.aces > 0:
for n in range(self.aces):
# check to see if the total points are more than 21.
if tpoints > 21:
# subtract 10 points for each ace.
tpoints = tpoints - 10
return (tpoints, raw_points)
def card_and_rank(self, card):
z = card.split()
rank = z[0]
return (card, rank)
def split_test(self):
card_a, rank_a = self.card_and_rank(self.hand_a[0])
card_b, rank_b = self.card_and_rank(self.hand_a[1])
val_a = game.deck.values[rank_a]
val_b = game.deck.values[rank_b]
if self.bet * 2 > stack.stored_end:
print "You don't have enough cash to split."
time.sleep(2)
return 'no'
elif game.deck.split_counter == 1:
return 'no'
elif val_a == val_b:
return 'split'
else:
return 'no'
def hos(self):
# hos = hit or stick
os.system("clear")
self.hand_points, self.raw_points = self.points()
print "\n"
# show dealer's hand
print "Dealer's up card is:\n%r\n" % game.deck.d_hand.show_card(0)
# show starting hand
self.show_hand()
self.softness(self.hand_points, self.raw_points)
print "\nYou're bet is $%d." % stack.stored_bet
print "Your stack is (less your current bet) $%d" % (stack.stored_end - stack.stored_bet)
x = self.black_jack_check()
if x == 'black_jack':
self.black_jack = 1
answer = 'stick'
self.check_hand(answer)
if self.split_test() == 'split':
answers = ['hit', 'stick', 'double', 'split']
while True:
print "\nWould you like to 'hit', 'stick', 'double' down or 'split'?"
if self.hand_points == 21:
answer = 'stick'
print "You have 21!"
time.sleep(.5)
break
else:
answer = raw_input(' >')
if answer in answers:
print "end of hos func"
break
else:
answers = ['hit', 'stick', 'double']
while True:
print "\nWould you like to 'hit', 'stick' or 'double'?"
if self.hand_points == 21:
answer = 'stick'
print "You have 21!"
time.sleep(.5)
break
else:
answer = raw_input(' >')
if answer in answers:
print "end of hos func"
break
self.check_hand(answer)
def check_hand(self, answer):
print "\nYou said %r." % answer
# hit
if answer == 'hit':
self.hit()
if self.hand_points > 21:
self.status = 'completed'
print "Your busted"
print "need to go to end game"
self.status = 'completed'
return 'done'
hl = len(self.hand_a.keys())
if hl == 5:
self.status = 'completed'
return 'done'
self.hos()
# stick
elif answer == 'stick':
self.status = 'completed'
print "need to call dhos and end the game"
# double
elif answer == 'double':
t_bet = stack.stored_bet # temp bet
t_end = stack.stored_end # temp stack balance (before bet)
t_bal = t_end - t_bet # what would the stack be if bet subtracted?
if t_bet > t_bal:
print "You don't have enough to doule down."
print "need to continue with hand - should check this when asking the question."
raw_input("Please hit enter to continue")
else:
print "\nYou doubled down."
stack.stored_bet = stack.stored_bet * 2
self.bet = self.bet * 2
print "Your bet is now $%d." % stack.stored_bet
self.hit()
self.show_hand()
self.status = 'completed'
time.sleep(3)
# split
elif answer == 'split':
if game.deck.split_counter == 0:
split_hands_dict = game.deck.split_algo(game.deck.start_hand)
ln = len(split_hands_dict)
for x in range(ln):
split_hands_dict[x].hos()
else:
print "Sorry, but no more splits."
time.sleep(2)
else:
print "something went horribly wrong."
exit(0)
def softness(self, points, raw_points):
# returns soft hand if hand is soft
if self.aces > 0:
nap = raw_points - (self.aces * 11) # = non-ace - points
if nap + 11 < 21:
print "\n%s has a soft %d" % (self.name, points)
print " _ " * 10
else:
print "%s has %d points. a" % (self.name, points)
print " _ " * 10
else:
print "%s has %d points." % (self.name, points)
print " _ " * 10
def black_jack_check(self):
# print " _ " * 10
# print "\n"
zz = {}
for i in range(len(self.hand_a.keys())):
card, rank = self.card_and_rank(self.hand_a[i])
# print "card is %r and rank is %r" % (card, rank)
zz[i] = rank
i += 1
if zz[0] == 'Ace' and zz[1] == "Jack":
# print "zz[0] is %r and zz[1] is %r a " % (zz[0], zz[1])
print "\nBlack Jack! You Win!\n"
time.sleep(1.5)
return "black_jack"
elif zz[0] == 'Jack' and zz[1] == 'Ace':
# print "zz[0] is %r and zz[1] is %r b" % (zz[0], zz[1])
print "\nBlack Jack! You Win!\n"
time.sleep(1.5)
return "black_jack"
else:
return 0
def hit(self):
print "hit method"
k = len(game.deck.full_deck.keys())
print k
new_card = game.deck.full_deck.pop(random.choice(game.deck.full_deck.keys()))
# hl = len(game.deck.start_hand.hand_a.keys()) # hl is hand length
hl = len(self.hand_a.keys()) # hl is hand length
print hl
# add new card tto hand
self.hand_a[hl] = new_card # insert new hard into hand of the given instance.
# add new opints to self.hand_points
self.hand_points, self.raw_points = self.points()
class Game():
def __init__(self):
self.hand_dict = {} # this will be a dict of all the hand instances created by Hand.
self.incomplete_hands = [] # hands yet to be played
self.compltete_hands = {} # hands done being played
def collect_hands(self):
# loops trough Hand.instances and unpacks into indivudual hands
print "\nbegin collect_hands\n"
i = 0
for handy in Hand.instances:
self.hand_dict.setdefault(handy.name, handy.hand_a)
i += 1
print self.hand_dict
print "\n"
for player in self.hand_dict:
print player
n = 0
for n in range(len(self.hand_dict[player])):
print self.hand_dict[player][n]
n += 1
print "print card rows"
# list of rows
first_cards = []
second_cards = []
third_cards = []
fourth_cards = []
fifth_cards = []
list_of_rows_raw = [first_cards, second_cards, third_cards, fourth_cards, fifth_cards]
for x in self.hand_dict:
first_cards.append(self.hand_dict[x][0])
for y in self.hand_dict:
second_cards.append(self.hand_dict[y][1])
table = texttable.Texttable()
header = self.hand_dict.keys()
table.header(header)
table.add_rows([first_cards, second_cards], header=False)
print table.draw()
def end_game(self):
# check to see how each completed hand did against the dealer
dpoints = self.deck.d_hand.hand_points
for hand in Hand.instances:
hand.stack_change = 0
if hand.status == 'completed':
# print "hand is %r" hand.name
print "hand points are %r" % hand.hand_points
print "dpoints are %r" % dpoints
print "bet is %r" % hand.bet
if hand.hand_points == 21:
if hand.black_jack == 1:
hand.stack_change = hand.stack_change + ((float(3)/2) * hand.bet)
hand.outcome = "Black Jack!!"
else:
hand.stack_change += hand.bet
hand.outcome = "Win"
elif hand.hand_points > 21:
hand.stack_change -= hand.bet
hand.outcome = "Lose"
elif dpoints > 21:
hand.stack_change += hand.bet
hand.outcome = "Win"
elif hand.hand_points < dpoints:
hand.stack_change -= hand.bet
hand.outcome = "Lose"
elif hand.hand_points > dpoints:
hand.stack_change += hand.bet
hand.outcome = "Win"
elif hand.hand_points == dpoints:
hand.stack_change + 0
hand.outcome = "Push"
else:
print "not sure what to tell you"
exit(0)
self.check_score()
def check_score(self):
#check to see if player has money to play again
total_winnings = 0
for hand in Hand.instances:
total_winnings = total_winnings + hand.stack_change
if stack.stored_end + total_winnings < 0:
print "You're out of cash. Goodbye!"
exit(0)
else:
stack.stored_end += total_winnings
self.replay(0, total_winnings)
def replay(self, miss_type, total_winnings):
# show table of hands
os.system("clear")
print "Your hands: \n"
hands_dict = {}
bets_dict = {}
outcomes_dict = {}
points_dict = {}
for hand in Hand.instances:
hands_dict.setdefault(hand.name, hand.hand_a)
bets_dict.setdefault(hand.name, hand.bet)
outcomes_dict.setdefault(hand.name, hand.outcome)
points_dict.setdefault(hand.name, hand.hand_points)
first_cards = []
second_cards = []
third_cards = []
fourth_cards = []
fifth_cards = []
bets_list = []
outcomes_list = []
points_list = []
for hand in hands_dict:
first_cards.append(hands_dict[hand].get(0))
second_cards.append(hands_dict[hand].get(1))
third_cards.append(hands_dict[hand].get(2))
fourth_cards.append(hands_dict[hand].get(3))
fifth_cards.append(hands_dict[hand].get(4))
bets_list.append("Bet is %r" % bets_dict[hand])
points_list.append("Points are %r" % points_dict[hand])
outcomes_list.append(outcomes_dict[hand])
header = hands_dict.keys()
table = texttable.Texttable()
table.header(header)
table.add_rows([first_cards, second_cards, third_cards, fourth_cards, fifth_cards, points_list, bets_list, outcomes_list], header = False)
print table.draw()
print "\n"
self.deck.d_hand.show_hand()
print "Dealer's points are %r." % self.deck.d_hand.hand_points
print "\nYou won $%r" % total_winnings
print "Your stack is now $%r\n" % stack.stored_end
if stack.stored_end <=0:
print "You're out of cash. Better luck next time!"
exit(0)
while True:
print "\nWould you like to play again?"
a = raw_input(' >')
if a == 'no':
print "Thanks for playing."
print "You ended up with $%d\n" % stack.stored_end
exit(0)
elif a =='yes':
hil = len(Hand.instances) # hil = hand instances length
for x in range(hil):
del Hand.instances[x-1]
time.sleep(1)
game.play_game(1, total_winnings)
break
else:
print "just 'yes' or 'no' please."
time.sleep(1)
def load_inc_hands(self):
# load first opening hand into incomplete hadns dict.
# remove dealer hand
lnth = len(Hand.instances)
for x in range(lnth):
if Hand.instances[x-1].name == 'Dealer':
del Hand.instances[x-1]
lnth = len(Hand.instances)
for z in range(lnth):
self.incomplete_hands.append(Hand.instances[z].name)
def play_game(self, replay, total_winnings):
# start
self.deck = DECK()
if replay == 1:
self.stack = Stack(1 , total_winnings)
os.system("clear")
print "Let's play!\n"
print " _ " * 10
begin = stack.stored_end # need this here for when game is replayed
begin, change, end = stack.account(0, begin) #laod account func with initical balance
print "You have $%d in your stack.\n" % end
print " _ " * 10
time.sleep(0.5)
play_deck = self.deck.full_deck
# bet
stack.bet_test(0)
bet = stack.stored_bet
# deal
self.deck.deal()
# attach the bet to the starting hand
self.deck.start_hand.bet = bet
os.system("clear")
print "deck has %r cads" % len(play_deck.keys())
print "play_game method of Game class\n"
# load incomeplete hands dict
self.load_inc_hands()
# go thorugh each hand and hit or stick
for hand in Hand.instances:
if hand.status == 'incomplete':
print "you're stuck in the hos loop"
hand.hos()
# go to dealer's hand
self.deck.dhos()
exit(0)
if __name__ == '__main__':
game = Game()
stack = Stack(0, 0)
stack.load_account()
game.play_game(0, 0)
First, if there's a better way to get the code in here than copy and paste, please let me know. Checking all the indents in python is a bit of a pain.
Second, please rip up this code! I'm trying to learn Python on my own and need all the feedback I can get. Please comment on everything: best practices, conventions...etc. Any and all comments welcome.
Thanks.