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.
DECK()
class; it is convention to use CapWords for class names. \$\endgroup\$from random import choice
or replace all instances ofrandom.choice
withchoice
\$\endgroup\$