Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Peter Rzepka
4,118 Pointshow do i input a score or betting money me vs the dealer? and change deck size?
im using Michael Dawsons book Python Programming for the absolute beginner third edit.
http://www.delmarlearning.com/companions/content/1435455002/downloads/index.asp?isbn=1435455002
Chapter 9 has the source code for this blackjack program which imports BlackJack.py, Cards.py and Games.py,
how do i input a score or betting money me vs the dealer? and change deck size?
# Blackjack
# From 1 to 7 players compete against a dealer
import cards, games
class BJ_Card(cards.Card):
""" A Blackjack Card. """
ACE_VALUE = 1
@property
def value(self):
if self.is_face_up:
v = BJ_Card.RANKS.index(self.rank) + 1
if v > 10:
v = 10
else:
v = None
return v
class BJ_Deck(cards.Deck):
""" A Blackjack Deck. """
def populate(self):
for suit in BJ_Card.SUITS:
for rank in BJ_Card.RANKS:
self.cards.append(BJ_Card(rank, suit))
class BJ_Hand(cards.Hand):
""" A Blackjack Hand. """
def __init__(self, name):
super(BJ_Hand, self).__init__()
self.name = name
def __str__(self):
rep = self.name + ":\t" + super(BJ_Hand, self).__str__()
if self.total:
rep += "(" + str(self.total) + ")"
return rep
@property
def total(self):
# if a card in the hand has value of None, then total is None
for card in self.cards:
if not card.value:
return None
# add up card values, treat each Ace as 1
t = 0
for card in self.cards:
t += card.value
# determine if hand contains an Ace
contains_ace = False
for card in self.cards:
if card.value == BJ_Card.ACE_VALUE:
contains_ace = True
# if hand contains Ace and total is low enough, treat Ace as 11
if contains_ace and t <= 11:
# add only 10 since we've already added 1 for the Ace
t += 10
return t
def is_busted(self):
return self.total > 21
class BJ_Player(BJ_Hand):
""" A Blackjack Player. """
def is_hitting(self):
response = games.ask_yes_no("\n" + self.name + ", do you want a hit? (Y/N): ")
return response == "y"
def bust(self):
print(self.name, "busts.")
self.lose()
def lose(self):
print(self.name, "loses.")
def win(self):
print(self.name, "wins.")
def push(self):
print(self.name, "pushes.")
class BJ_Dealer(BJ_Hand):
""" A Blackjack Dealer. """
def is_hitting(self):
return self.total < 17
def bust(self):
print(self.name, "busts.")
def flip_first_card(self):
first_card = self.cards[0]
first_card.flip()
class BJ_Game(object):
""" A Blackjack Game. """
def __init__(self, names):
self.players = []
for name in names:
player = BJ_Player(name)
self.players.append(player)
self.dealer = BJ_Dealer("Dealer")
self.deck = BJ_Deck()
self.deck.populate()
self.deck.shuffle()
@property
def still_playing(self):
sp = []
for player in self.players:
if not player.is_busted():
sp.append(player)
return sp
def __additional_cards(self, player):
while not player.is_busted() and player.is_hitting():
self.deck.deal([player])
print(player)
if player.is_busted():
player.bust()
def play(self):
# deal initial 2 cards to everyone
self.deck.deal(self.players + [self.dealer], per_hand = 2)
self.dealer.flip_first_card() # hide dealer's first card
for player in self.players:
print(player)
print(self.dealer)
# deal additional cards to players
for player in self.players:
self.__additional_cards(player)
self.dealer.flip_first_card() # reveal dealer's first
if not self.still_playing:
# since all players have busted, just show the dealer's hand
print(self.dealer)
else:
# deal additional cards to dealer
print(self.dealer)
self.__additional_cards(self.dealer)
if self.dealer.is_busted():
# everyone still playing wins
for player in self.still_playing:
player.win()
else:
# compare each player still playing to dealer
for player in self.still_playing:
if player.total > self.dealer.total:
player.win()
elif player.total < self.dealer.total:
player.lose()
else:
player.push()
# remove everyone's cards
for player in self.players:
player.clear()
self.dealer.clear()
def main():
print("\t\tWelcome to Blackjack!\n")
names = []
number = games.ask_number("How many players? (1 - 7): ", low = 1, high = 8)
for i in range(number):
name = input("Enter player name: ")
names.append(name)
print()
game = BJ_Game(names)
again = None
while again != "n":
game.play()
again = games.ask_yes_no("\nDo you want to play again?: ")
main()
input("\n\nPress the enter key to exit.")
# Cards Module
# Basic classes for a game with playing cards
class Card(object):
""" A playing card. """
RANKS = ["A", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "J", "Q", "K"]
SUITS = ["c", "d", "h", "s"]
def __init__(self, rank, suit, face_up = True):
self.rank = rank
self.suit = suit
self.is_face_up = face_up
def __str__(self):
if self.is_face_up:
rep = self.rank + self.suit
else:
rep = "XX"
return rep
def flip(self):
self.is_face_up = not self.is_face_up
class Hand(object):
""" A hand of playing cards. """
def __init__(self):
self.cards = []
def __str__(self):
if self.cards:
rep = ""
for card in self.cards:
rep += str(card) + "\t"
else:
rep = "<empty>"
return rep
def clear(self):
self.cards = []
def add(self, card):
self.cards.append(card)
def give(self, card, other_hand):
self.cards.remove(card)
other_hand.add(card)
class Deck(Hand):
""" A deck of playing cards. """
def populate(self):
for suit in Card.SUITS:
for rank in Card.RANKS:
self.add(Card(rank, suit))
def shuffle(self):
import random
random.shuffle(self.cards)
def deal(self, hands, per_hand = 1):
for rounds in range(per_hand):
for hand in hands:
if self.cards:
top_card = self.cards[0]
self.give(top_card, hand)
else:
print("Can't continue deal. Out of cards!")
if __name__ == "__main__":
print("This is a module with classes for playing cards.")
input("\n\nPress the enter key to exit.")
# Games
# Demonstrates module creation
class Player(object):
""" A player for a game. """
def __init__(self, name, score = 0):
self.name = name
self.score = score
def __str__(self):
rep = self.name + ":\t" + str(self.score)
return rep
def ask_yes_no(question):
"""Ask a yes or no question."""
response = None
while response not in ("y", "n"):
response = input(question).lower()
return response
def ask_number(question, low, high):
"""Ask for a number within a range."""
response = None
while response not in range(low, high):
response = int(input(question))
return response
if __name__ == "__main__":
print("You ran this module directly (and did not 'import' it).")
input("\n\nPress the enter key to exit.")
2 Answers
Nathan Tallack
22,164 PointsWow. Nice book! Your question is not a simple one to answer. But I can guide you a little and you can ask more questions and provide code examples of your work and I can help out. Be sure to surround your code with the three ` marks so that it formats right.
So, the main() function starts the game when you run blackjack.py from the command line. It creates your game object from the BJ_Game class passing in the list of your player names.
That object is where it all happens. You call the play method on it and the game runs. So lets focus on that object for the moment.
When it initializes it sets up some properties.
class BJ_Game(object):
""" A Blackjack Game. """
def __init__(self, names):
self.players = []
for name in names:
player = BJ_Player(name)
self.players.append(player)
self.dealer = BJ_Dealer("Dealer")
self.deck = BJ_Deck()
self.deck.populate()
self.deck.shuffle()
First thing you are going to want to do is add a new property for each player to store their currency. You see there that there is a player object being created from the BJ_Player class for each player. So in there is where you will be wanting to store that currency property. Right now that class does not have any object properties, so you will have to setup an init method and set self.currency and self.bet properties on it.
Now we are going to want to update the play method in the BJ_Game class so that we can place a bet before the hand is dealt. I would put it inside the loop that deals the cards down at line 135. It could look something like this.
def play(self):
# let everyone place their bets
# Loop through players
# Prompt player for bet amount
# Call method on player object to place bet
# deal initial 2 cards to everyone
self.deck.deal(self.players + [self.dealer], per_hand = 2)
self.dealer.flip_first_card() # hide dealer's first card
for player in self.players:
print(player)
print(self.dealer)
Now you will need to create that method on your player object allowing a bet to be placed. It will take in the bet amount and it will check that you have enough in your player currency property to cover the bet and will take that money from that amount. You could build some sanity checking in there returning true or false if the bet can be covered or not and prompting the player again for a different bet amount. Or you could display to the player how much currency they have at that prompt so they know how much they can bet. Or even both. :)
Finally you are going to need to update the BJ_Game object play method again where the dealer busts so that the players who are winning can be paid out. You update their currency with their winnings.
Not a bad start for you. :)
Peter Rzepka
4,118 PointsI was thinking proubly the "Option of how much to bet before each hand". there would NOT be a starting bankroll; so therefor it can go Negative. also to make things legit, also an "Option on how many decks" the player would want to be in play. "to setup an init method and set self.currency and self.bet properties on it."
class BJ_Game(object):
""" A Blackjack Game. """
def __init__(self, names):
self.players = []
for name in names:
player = BJ_Player(name)
self.players.append(player)
self.dealer = BJ_Dealer("Dealer")
self.deck = BJ_Deck()
self.deck.populate()
self.deck.shuffle()
def __init__(self, currency, bet):
self.currency = []
self.currency = #user input a value that goes into the list to keep track of a positive value or negative value
# i would also want this displayed right next to the player hand value count.
I would also have to retrigger the Betting to have it Double Down the previous bet on the table. proubly in this section; but this would only apply to the player being dealt a 10 or an 11 total value.
class BJ_Player(BJ_Hand):
""" A Blackjack Player. """
def is_doubling(self): #new variable is_doubling which refers to the players inital bet
response = games.ask_yes_no("\n" + self.name + ", do you want to Double Down? (Y/N): ")
return response == "y"
#if yes then double players inital set bet for this hand
#doubling would have to come first wether the player has a DEALT value of 10 or 11, additional One Card HitOnly.
#then a regular option to hit if the person dosent want to double down but yet still hituntil they want to stop as regular.
def is_hitting(self):
response = games.ask_yes_no("\n" + self.name + ", do you want a hit? (Y/N): ")
return response == "y"
def __additional_cards(self, player):
while not player.is_busted() and player.is_hitting():
self.deck.deal([player])
print(player)
if player.is_busted():
player.bust()
# or would the inital option to double down go here????
class Card(object):
""" A playing card. """
RANKS = ["A", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "J", "Q", "K"]
SUITS = ["c", "d", "h", "s"]
#Player chooses how many decks to play with so i dont know how to add additional decks per user input
Nathan Tallack
22,164 PointsAnd thus you found the rabbit hole. ;)
Take care not to let your improvements destablize your code. Now is a good time to start learning some version control and maybe a little bit of agile development skills.
There are courses on here for that. If you can pry yourself away from your code for a few hours get a GIT and SCRUM course under your belt. ;)