From 3b4716e7de627adfcefa5268a5afcf03a5d661d8 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Tue, 2 Jun 2015 17:09:26 -0400 Subject: [PATCH 01/22] created card class --- blackjack/card.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 blackjack/card.py diff --git a/blackjack/card.py b/blackjack/card.py new file mode 100644 index 0000000..ae27550 --- /dev/null +++ b/blackjack/card.py @@ -0,0 +1,7 @@ +class Card(): + def __init__(self, suit, rank): + self.suit = suit.lower() + self.rank = rank.lower() + + def __repr__(self): + return "{} of {}".format(self.rank.title(), self.suit.title()) From d6e09f5808fbc241dea996d87422f99ba9b5720c Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Tue, 2 Jun 2015 17:09:37 -0400 Subject: [PATCH 02/22] created deck class --- blackjack/deck.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 blackjack/deck.py diff --git a/blackjack/deck.py b/blackjack/deck.py new file mode 100644 index 0000000..3340f59 --- /dev/null +++ b/blackjack/deck.py @@ -0,0 +1,27 @@ +import random +from card import Card + + +class Deck(): + def __init__(self): + numbers = list(map(str, range(2, 11))) + ranks = ['ace', 'king', 'queen', 'jack'] + ranks.extend(numbers) + suits = ['hearts', 'spades', 'diamonds', 'clubs'] + self.card_list = [Card(suit, rank) for rank in ranks for suit in suits] + self.shuffle() + + def shuffle(self): + random.shuffle(self.card_list) + + def __repr__(self): + return str(self.card_list) + + def deal(self): + return self.card_list.pop() + + +deck = Deck() +print(deck) +print(deck.deal()) +print(deck) From 7a9dfddad5a69e203e5c70f1161807d711d67b8d Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Tue, 2 Jun 2015 17:29:30 -0400 Subject: [PATCH 03/22] added stubs for the remaining classes --- blackjack/dealer.py | 5 +++++ blackjack/game.py | 6 ++++++ blackjack/hand.py | 7 +++++++ blackjack/player.py | 7 +++++++ 4 files changed, 25 insertions(+) create mode 100644 blackjack/dealer.py create mode 100644 blackjack/game.py create mode 100644 blackjack/hand.py create mode 100644 blackjack/player.py diff --git a/blackjack/dealer.py b/blackjack/dealer.py new file mode 100644 index 0000000..42b6252 --- /dev/null +++ b/blackjack/dealer.py @@ -0,0 +1,5 @@ +""" +The Dealer inherits from player. It overwrites the display_hand method, and +it does not have anything to do with bets. It will also overwrite the input +method, which will hit or stand according to the stand_value. +""" diff --git a/blackjack/game.py b/blackjack/game.py new file mode 100644 index 0000000..d388b92 --- /dev/null +++ b/blackjack/game.py @@ -0,0 +1,6 @@ +""" +The Game class is responsible for managing all of the different aspects of the +game. It will contain the deck, as well as the player and dealer. It is +responsible for providing cards when a hit is requested. It is also +responsible for determining the winner of a hand. +""" diff --git a/blackjack/hand.py b/blackjack/hand.py new file mode 100644 index 0000000..80af47f --- /dev/null +++ b/blackjack/hand.py @@ -0,0 +1,7 @@ +""" +The Hand class will keep a collection of cards. It will use the rules to +determine the value of that hand. It will contain a boolean to keep track of +whether the hand is busted, and it will contain another boolean to keep track +of whether the hand is blackjack. It will have a method that will be used to +add cards to the hand. +""" diff --git a/blackjack/player.py b/blackjack/player.py new file mode 100644 index 0000000..b767242 --- /dev/null +++ b/blackjack/player.py @@ -0,0 +1,7 @@ +""" +The Player class is going to keep track of current "score" (or amount of +money) as well as the current bet amount. It will also handle player input ( +getting bet amounts, as well as asking if the player wants to hit or stand) +The Player will also be responsible for keeping track of his current hand as +well as displaying the hand when requested. +""" From df7bfa73531ee0e3d6d3d3e126b581134da3276a Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Tue, 2 Jun 2015 17:40:22 -0400 Subject: [PATCH 04/22] added basic tests to Card and Deck --- blackjack/card.py | 10 ++++++++++ blackjack/deck.py | 11 ++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/blackjack/card.py b/blackjack/card.py index ae27550..d2fabf5 100644 --- a/blackjack/card.py +++ b/blackjack/card.py @@ -5,3 +5,13 @@ def __init__(self, suit, rank): def __repr__(self): return "{} of {}".format(self.rank.title(), self.suit.title()) + +if __name__ == "__main__": + test_list = [("hearts", "king"), ("diamonds", "2")] + card_list = [Card(suit, rank) for suit, rank in test_list] + assert card_list[0].suit == "hearts" + assert card_list[1].suit == "diamonds" + assert card_list[0].rank == "king" + assert card_list[1].rank == "2" + assert str(card_list[0]) == "King of Hearts" + assert str(card_list[1]) == "2 of Diamonds" diff --git a/blackjack/deck.py b/blackjack/deck.py index 3340f59..d067454 100644 --- a/blackjack/deck.py +++ b/blackjack/deck.py @@ -20,8 +20,9 @@ def __repr__(self): def deal(self): return self.card_list.pop() - -deck = Deck() -print(deck) -print(deck.deal()) -print(deck) +if __name__ == "__main__": + test_deck = Deck() + example_card = Card("hearts", "3") + assert len(test_deck.card_list) == 52 + assert type(test_deck.deal()) == type(example_card) + assert len(test_deck.card_list) == 51 From 5800b4992d088ce9faf88b0ecdaaf3dbdb474da9 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 09:03:26 -0400 Subject: [PATCH 05/22] changed deal to draw --- blackjack/deck.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blackjack/deck.py b/blackjack/deck.py index d067454..62c5b90 100644 --- a/blackjack/deck.py +++ b/blackjack/deck.py @@ -17,12 +17,12 @@ def shuffle(self): def __repr__(self): return str(self.card_list) - def deal(self): + def draw(self): return self.card_list.pop() if __name__ == "__main__": test_deck = Deck() example_card = Card("hearts", "3") assert len(test_deck.card_list) == 52 - assert type(test_deck.deal()) == type(example_card) + assert type(test_deck.draw()) == type(example_card) assert len(test_deck.card_list) == 51 From 4b98b3cf88c6ca77bea2f116fe1c38a1a92e19a8 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 13:27:38 -0400 Subject: [PATCH 06/22] deck now has a private card_list --- blackjack/deck.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/blackjack/deck.py b/blackjack/deck.py index 62c5b90..bee8c2a 100644 --- a/blackjack/deck.py +++ b/blackjack/deck.py @@ -8,17 +8,23 @@ def __init__(self): ranks = ['ace', 'king', 'queen', 'jack'] ranks.extend(numbers) suits = ['hearts', 'spades', 'diamonds', 'clubs'] - self.card_list = [Card(suit, rank) for rank in ranks for suit in suits] + self._card_list = [Card(suit, rank) + for rank in ranks for suit in suits] self.shuffle() + @property + def card_list(self): + return self._card_list + def shuffle(self): random.shuffle(self.card_list) - def __repr__(self): - return str(self.card_list) - def draw(self): - return self.card_list.pop() + return self._card_list.pop() + + @property + def card_list_display(self): + return '\n'.join(map(str, self._card_list)) if __name__ == "__main__": test_deck = Deck() From 38eb7638b59953d8ef6e776c9bf04b11f1fdcb3f Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 13:34:54 -0400 Subject: [PATCH 07/22] moved card_list creation to a method --- blackjack/deck.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/blackjack/deck.py b/blackjack/deck.py index bee8c2a..a96b53d 100644 --- a/blackjack/deck.py +++ b/blackjack/deck.py @@ -4,12 +4,7 @@ class Deck(): def __init__(self): - numbers = list(map(str, range(2, 11))) - ranks = ['ace', 'king', 'queen', 'jack'] - ranks.extend(numbers) - suits = ['hearts', 'spades', 'diamonds', 'clubs'] - self._card_list = [Card(suit, rank) - for rank in ranks for suit in suits] + self.create_card_list() self.shuffle() @property @@ -22,6 +17,14 @@ def shuffle(self): def draw(self): return self._card_list.pop() + def create_card_list(self): + numbers = list(map(str, range(2, 11))) + ranks = ['ace', 'king', 'queen', 'jack'] + ranks.extend(numbers) + suits = ['hearts', 'spades', 'diamonds', 'clubs'] + self._card_list = [Card(suit, rank) + for rank in ranks for suit in suits] + @property def card_list_display(self): return '\n'.join(map(str, self._card_list)) From 53e3f7597c50a815579ed7caf8c785603db1def3 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 16:58:05 -0400 Subject: [PATCH 08/22] did too much again. I'm sad. :-( --- blackjack/deck.py | 2 +- blackjack/hand.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/blackjack/deck.py b/blackjack/deck.py index a96b53d..e529dd3 100644 --- a/blackjack/deck.py +++ b/blackjack/deck.py @@ -12,7 +12,7 @@ def card_list(self): return self._card_list def shuffle(self): - random.shuffle(self.card_list) + random.shuffle(self._card_list) def draw(self): return self._card_list.pop() diff --git a/blackjack/hand.py b/blackjack/hand.py index 80af47f..bcd948e 100644 --- a/blackjack/hand.py +++ b/blackjack/hand.py @@ -5,3 +5,48 @@ of whether the hand is blackjack. It will have a method that will be used to add cards to the hand. """ +class Hand(): + def __init__(self): + self._card_list = [] + self.score = 0 + self.blackjack = False + self.busted = False + + @property + def card_list(self): + return self.card_list + + def get_score(self): + return sum([card.value for card in card_list]) + + def start_card_value(self, rank): + if not card.rank.isalpha() and card.rank != "ace": + return int(card.rank) + elif card.rank != "ace": + return 10 + self.soft = True + return 11 + + def reevaluate_score(self): + if self.get_score() > 21: + for card in self._card_list: + if card.rank == "ace" and card.value == 11: + card.value = 1 + break + elif self.get_score == 21: + self.blackjack = True + return + if self.get_score() > 21: + self.busted = True + + def add_card(self, card): + card.value = self.start_card_value(card.rank) + self._card_list.append(card) + self.reevaluate_score() + + @property + def card_list_display(self, show_all=True): + card_list = self.card_list + if not show_all: + card_list[0] = "" + return ", ".join(card_list) From 7160cc5aad40e9ec28c2f579f2219b58ac95795c Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:26:08 -0400 Subject: [PATCH 09/22] finished hand, including tests --- blackjack/hand.py | 63 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/blackjack/hand.py b/blackjack/hand.py index bcd948e..7eb13c9 100644 --- a/blackjack/hand.py +++ b/blackjack/hand.py @@ -1,52 +1,77 @@ -""" -The Hand class will keep a collection of cards. It will use the rules to -determine the value of that hand. It will contain a boolean to keep track of -whether the hand is busted, and it will contain another boolean to keep track -of whether the hand is blackjack. It will have a method that will be used to -add cards to the hand. -""" class Hand(): def __init__(self): self._card_list = [] self.score = 0 self.blackjack = False self.busted = False + self.soft = False @property def card_list(self): - return self.card_list + return self._card_list def get_score(self): - return sum([card.value for card in card_list]) + return sum([card.value for card in self.card_list]) def start_card_value(self, rank): - if not card.rank.isalpha() and card.rank != "ace": - return int(card.rank) - elif card.rank != "ace": + if not rank.isalpha() and rank != "ace": + return int(rank) + elif rank != "ace": return 10 self.soft = True return 11 - def reevaluate_score(self): + def evaluate_score(self): if self.get_score() > 21: - for card in self._card_list: + for card in self.card_list: if card.rank == "ace" and card.value == 11: card.value = 1 + self.soft = False break - elif self.get_score == 21: + if 11 in [card.value for card in self.card_list]: + self.soft = True + if self.get_score() == 21: self.blackjack = True return if self.get_score() > 21: self.busted = True + self.blackjack = False def add_card(self, card): card.value = self.start_card_value(card.rank) + card.__str__ = lambda self: "{} of {} is worth {}".format( + self.rank.title(), self.suit.title(), self.value) self._card_list.append(card) - self.reevaluate_score() + self.evaluate_score() - @property def card_list_display(self, show_all=True): card_list = self.card_list if not show_all: - card_list[0] = "" - return ", ".join(card_list) + card_list[0] = Card("Cards", "Unknown") + card_list[0].value = 0 + return ", ".join(map(str, card_list)) + +if __name__ == "__main__": + from card import Card + test_hand = Hand() + test_hand.add_card(Card("Spades", "Ace")) + assert test_hand.get_score() == 11 + test_hand.add_card(Card("Clubs", "Ace")) + assert test_hand.get_score() == 12 + test_hand.add_card(Card("Diamonds", "5")) + assert test_hand.get_score() == 17 + assert test_hand.soft + assert not test_hand.blackjack + assert not test_hand.busted + test_hand.add_card(Card("Hearts", "Queen")) + assert test_hand.get_score() == 17 + test_hand.add_card(Card("Hearts", "4")) + assert test_hand.get_score() == 21 + assert not test_hand.soft + assert not test_hand.busted + assert test_hand.blackjack + test_hand.add_card(Card("Clubs", "Jack")) + assert test_hand.busted + assert not test_hand.blackjack + assert not test_hand.soft + assert test_hand.get_score() == 31 From 4234a09ff40bc4d0328753a5e38c39e2cf33074f Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:26:34 -0400 Subject: [PATCH 10/22] started implementing player --- blackjack/player.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/blackjack/player.py b/blackjack/player.py index b767242..8554ec6 100644 --- a/blackjack/player.py +++ b/blackjack/player.py @@ -1,7 +1,20 @@ -""" -The Player class is going to keep track of current "score" (or amount of -money) as well as the current bet amount. It will also handle player input ( -getting bet amounts, as well as asking if the player wants to hit or stand) -The Player will also be responsible for keeping track of his current hand as -well as displaying the hand when requested. -""" +from hand import Hand + +class Player(): + def __init__(self): + self.score = 100 + + def start_game(self): + self.deck = Hand() + + def add_card(self, card): + self.deck.add_card(card) + + def is_busted(self): + return self.deck.busted + + def has_blackjack(self): + return self.deck.blackjack + + def has_soft_hand(self): + return self.deck.soft From 9ed2027ac332cf69c55b762888d1e6ef185cd127 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:29:10 -0400 Subject: [PATCH 11/22] added bet function --- blackjack/player.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/blackjack/player.py b/blackjack/player.py index 8554ec6..d14a091 100644 --- a/blackjack/player.py +++ b/blackjack/player.py @@ -1,5 +1,6 @@ from hand import Hand + class Player(): def __init__(self): self.score = 100 @@ -7,6 +8,9 @@ def __init__(self): def start_game(self): self.deck = Hand() + def end_game(self): + pass + def add_card(self, card): self.deck.add_card(card) @@ -18,3 +22,7 @@ def has_blackjack(self): def has_soft_hand(self): return self.deck.soft + + def bet(self, amount=10): + self.score -= amount + return amount From ae24687c68b45d42c8a5723d45bef9ef19a83e87 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:33:53 -0400 Subject: [PATCH 12/22] added display_hand property --- blackjack/player.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/blackjack/player.py b/blackjack/player.py index d14a091..2c16d5e 100644 --- a/blackjack/player.py +++ b/blackjack/player.py @@ -26,3 +26,10 @@ def has_soft_hand(self): def bet(self, amount=10): self.score -= amount return amount + + def add_score(self, amount): + self.score += amount + + @property + def display_hand(self): + return self.hand.card_list_display() From f9ae386513b37f210455395f1538cdca19fd857d Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:34:23 -0400 Subject: [PATCH 13/22] created Dealer class that inherits from Player --- blackjack/dealer.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/blackjack/dealer.py b/blackjack/dealer.py index 42b6252..371c3ed 100644 --- a/blackjack/dealer.py +++ b/blackjack/dealer.py @@ -1,5 +1,11 @@ -""" -The Dealer inherits from player. It overwrites the display_hand method, and -it does not have anything to do with bets. It will also overwrite the input -method, which will hit or stand according to the stand_value. -""" +from player import Player + + +class Dealer(Player): + def __init__(self): + del self.bet + del self.add_score + + @property + def display_hand(self): + return self.hand.card_list_display(False) From a434d4fd1fb8dd83faea4dca9f66e0964d1c7e0b Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:55:02 -0400 Subject: [PATCH 14/22] created start for Game class --- blackjack/game.py | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/blackjack/game.py b/blackjack/game.py index d388b92..3234a27 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -1,6 +1,31 @@ -""" -The Game class is responsible for managing all of the different aspects of the -game. It will contain the deck, as well as the player and dealer. It is -responsible for providing cards when a hit is requested. It is also -responsible for determining the winner of a hand. -""" +from player import Player +from dealer import Dealer +from deck import Deck +from display import Display + + +class Game(): + def __init__(self): + self.player = Player() + self.dealer = Dealer() + self.deck = Deck() + self.display = Display() + + def print_display(self): + self.display.print_display() + + def start_round(self): + self.deck = Deck() + self.player.bet(self.get_bet_input()) + + def get_play_input(self): + while input("Do you want to play again? (y/n) > ").lower()\ + not in ("y", "n"): + print("Please enter 'y' or 'n'") + + def get_bet_input(self): + # return input("How much do you want to bet?") + print("Betting 10.") + return 10 + + def get_stand_or_hit() From 7285c33e3c98ad6c020a1a70db4242bf911d7477 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 20:55:13 -0400 Subject: [PATCH 15/22] started stubbing out Display class --- blackjack/display.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 blackjack/display.py diff --git a/blackjack/display.py b/blackjack/display.py new file mode 100644 index 0000000..c8f1807 --- /dev/null +++ b/blackjack/display.py @@ -0,0 +1,6 @@ +class Display(): + def __init__(self): + pass + + def print_display(self): + pass From 9f0b648071fe63b3e7babc4b1fbcbef26e445693 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 22:20:13 -0400 Subject: [PATCH 16/22] waaaaaaaay too much --- blackjack/dealer.py | 4 ++ blackjack/display.py | 24 +++++++- blackjack/game.py | 142 ++++++++++++++++++++++++++++++++++++++++--- blackjack/player.py | 3 + 4 files changed, 160 insertions(+), 13 deletions(-) diff --git a/blackjack/dealer.py b/blackjack/dealer.py index 371c3ed..7d0be5c 100644 --- a/blackjack/dealer.py +++ b/blackjack/dealer.py @@ -9,3 +9,7 @@ def __init__(self): @property def display_hand(self): return self.hand.card_list_display(False) + + @property + def display_full_hand(self): + return self.hand.card_list_display() diff --git a/blackjack/display.py b/blackjack/display.py index c8f1807..36963ea 100644 --- a/blackjack/display.py +++ b/blackjack/display.py @@ -1,6 +1,24 @@ +import os + + class Display(): - def __init__(self): - pass + def __init__(self, number_of_persistent_lines=1): + self.number_of_persistent_lines = number_of_persistent_lines + self.reset() def print_display(self): - pass + os.system("clear") + map(print, self.lines) + self.lines = self.lines[:self.number_of_persistent_lines] + + def set_display(self, message, position): + if position >= number_of_persistent_lines: + return + self.lines[position] = message + + def add_messages(self, *args): + for message in args: + self.lines.append(message) + + def reset(self): + self.lines = ["" for i in range(self.number_of_persistent_lines)] diff --git a/blackjack/game.py b/blackjack/game.py index 3234a27..dba3f2b 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -8,24 +8,146 @@ class Game(): def __init__(self): self.player = Player() self.dealer = Dealer() - self.deck = Deck() - self.display = Display() + self.display = Display(7) + self.pot = 0 - def print_display(self): + def print_display(self, wait=False): + self.update_display() self.display.print_display() + if wait: + self.get_continue() + + def update_display(self): + display_list = ["Dealer:", self.dealer.display_hand(False), + "Score: " + str(self.dealer.get_hand_value()) + + " | Pot: " + str(self.pot), + "- "*20, "You:", self.player.display_hand(), + "Score: " + str(self.player.get_hand_value()) + + " | Money: " + str(self.player.score)] + for index, string in enumerate(display_list): + self.display.set_display(string, index) def start_round(self): self.deck = Deck() - self.player.bet(self.get_bet_input()) + self.pot = self.player.bet(self.get_bet_input()) + self.player.start_game() + self.dealer.start_game() + self.add_message("Welcome to BlackJack!") + self.get_continue() + self.initial_deal() + if dealer.has_blackjack() and player.has_blackjack(): + self.add_message("The round is a push.") + self.print_display(True) + return False + elif player.has_blackjack(): + self.add_message("You have BlackJack!") + self.add_message("You win the hand!") + self.print_display(True) + self.add_message("You won {}.".format(bet)) + self.player.add_score(bet) + self.bet = 0 + self.print_display(True) + return False + elif dealer.has_blackjack(): + self.add_message("Dealer has BlackJack.") + self.add_message("You lose the hand.") + self.print_display(True) + self.bet = 0 + return False + return self.play() + + def initial_deal(self): + for i in range(2): + self.player.add_card(self.deal()) + self.update_display(True) + self.dealer.add_card(self.deal()) + self.update_display(True) - def get_play_input(self): - while input("Do you want to play again? (y/n) > ").lower()\ - not in ("y", "n"): - print("Please enter 'y' or 'n'") + def get_input(self, type): + self.print_display() + if type == "hand": + return self.get_hand_input() + elif type == "bet": + return self.get_bet_input() + elif type = "choice": + return self.get_stand_or_hit() + + def get_hand_input(self): + while True: + string = "Do you want to play another hand? (y/n) > " + value = input(string).lower() + if value in ("y", "n"): + return value + self.add_message("Please enter 'y' or 'n'") + self.print_display() def get_bet_input(self): # return input("How much do you want to bet?") - print("Betting 10.") + self.add_message("Betting 10.") return 10 - def get_stand_or_hit() + def get_stand_or_hit(self): + while True: + string = "Do you want to stand or hit? > " + value = input(string).lower() + if value in ("stand", "hit"): + return value + self.add_message("Please enter 'stand' or 'hit'") + self.print_display() + + def add_message(self, message): + self.display.add_messages(message) + + def get_continue(self): + input("Press Enter to continue.") + + def deal(self): + return self.deck.draw() + + def player_play(self): + while self.get_input("choice") == "hit": + self.player.add_card(self.draw()) + if self.player.has_blackjack(): + self.add_message("You have BlackJack!") + self.print_display(True) + return True + elif self.player.is_busted(): + self.add_message("You have busted.") + self.print_display(True) + return False + return True + + def dealer_play(self): + while self.dealer.get_hand_value() < 17: + self.dealer.add_card(self.draw()) + if self.dealer.has_blackjack(): + self.add_message("Dealer has BlackJack.") + self.print_display(True) + break + if self.dealer.is_busted(): + self.add_message("Dealer is busted!") + self.print_display(True) + break + + def play(self): + if self.player_play(): + self.dealer_play() + if dealer.has_blackjack() and player.has_blackjack(): + self.add_message("The round is a push.") + self.print_display(True) + return False + elif player.has_blackjack(): + self.add_message("You have BlackJack!") + self.add_message("You win the hand!") + self.print_display(True) + self.add_message("You won {}.".format(bet)) + self.player.add_score(bet) + self.bet = 0 + self.print_display(True) + return False + elif dealer.has_blackjack(): + self.add_message("Dealer has BlackJack.") + self.add_message("You lose the hand.") + self.print_display(True) + self.bet = 0 + return False diff --git a/blackjack/player.py b/blackjack/player.py index 2c16d5e..bc9c5c7 100644 --- a/blackjack/player.py +++ b/blackjack/player.py @@ -30,6 +30,9 @@ def bet(self, amount=10): def add_score(self, amount): self.score += amount + def get_hand_value(self): + return self.hand. + @property def display_hand(self): return self.hand.card_list_display() From 32c1251692995649149cde600d4a4afe2451d349 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Wed, 3 Jun 2015 23:15:58 -0400 Subject: [PATCH 17/22] working game with lots of bugs --- blackjack/dealer.py | 19 +++++++------ blackjack/display.py | 5 ++-- blackjack/game.py | 64 ++++++++++++++++++++++++++++---------------- blackjack/hand.py | 19 ++++++++----- blackjack/main.py | 5 ++++ blackjack/player.py | 15 +++++------ 6 files changed, 79 insertions(+), 48 deletions(-) create mode 100644 blackjack/main.py diff --git a/blackjack/dealer.py b/blackjack/dealer.py index 7d0be5c..c9da499 100644 --- a/blackjack/dealer.py +++ b/blackjack/dealer.py @@ -3,13 +3,16 @@ class Dealer(Player): def __init__(self): - del self.bet - del self.add_score + pass - @property - def display_hand(self): - return self.hand.card_list_display(False) + def display_hand(self, hidden=False): + return self.hand.card_list_display(hidden) - @property - def display_full_hand(self): - return self.hand.card_list_display() + def bet(self): + pass + + def add_score(self): + pass + + def get_hand_value(self, hidden=False): + return self.hand.get_score(hidden) diff --git a/blackjack/display.py b/blackjack/display.py index 36963ea..ef2092d 100644 --- a/blackjack/display.py +++ b/blackjack/display.py @@ -8,11 +8,12 @@ def __init__(self, number_of_persistent_lines=1): def print_display(self): os.system("clear") - map(print, self.lines) + for line in self.lines: + print(line) self.lines = self.lines[:self.number_of_persistent_lines] def set_display(self, message, position): - if position >= number_of_persistent_lines: + if position >= self.number_of_persistent_lines: return self.lines[position] = message diff --git a/blackjack/game.py b/blackjack/game.py index dba3f2b..33c9298 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -17,9 +17,9 @@ def print_display(self, wait=False): if wait: self.get_continue() - def update_display(self): - display_list = ["Dealer:", self.dealer.display_hand(False), - "Score: " + str(self.dealer.get_hand_value()) + + def update_display(self, hidden=True): + display_list = ["Dealer:", self.dealer.display_hand(hidden), + "Score: " + str(self.dealer.get_hand_value(hidden)) + " | Pot: " + str(self.pot), "- "*20, "You:", self.player.display_hand(), "Score: " + str(self.player.get_hand_value()) + @@ -35,20 +35,20 @@ def start_round(self): self.add_message("Welcome to BlackJack!") self.get_continue() self.initial_deal() - if dealer.has_blackjack() and player.has_blackjack(): + if self.dealer.has_blackjack() and self.player.has_blackjack(): self.add_message("The round is a push.") self.print_display(True) return False - elif player.has_blackjack(): + elif self.player.has_blackjack(): self.add_message("You have BlackJack!") self.add_message("You win the hand!") self.print_display(True) - self.add_message("You won {}.".format(bet)) - self.player.add_score(bet) + self.add_message("You won {}.".format(self.bet)) + self.player.add_score(self.bet) self.bet = 0 self.print_display(True) return False - elif dealer.has_blackjack(): + elif self.dealer.has_blackjack(): self.add_message("Dealer has BlackJack.") self.add_message("You lose the hand.") self.print_display(True) @@ -59,9 +59,9 @@ def start_round(self): def initial_deal(self): for i in range(2): self.player.add_card(self.deal()) - self.update_display(True) + self.print_display(True) self.dealer.add_card(self.deal()) - self.update_display(True) + self.print_display(True) def get_input(self, type): self.print_display() @@ -69,7 +69,7 @@ def get_input(self, type): return self.get_hand_input() elif type == "bet": return self.get_bet_input() - elif type = "choice": + elif type == "choice": return self.get_stand_or_hit() def get_hand_input(self): @@ -106,7 +106,7 @@ def deal(self): def player_play(self): while self.get_input("choice") == "hit": - self.player.add_card(self.draw()) + self.player.add_card(self.deal()) if self.player.has_blackjack(): self.add_message("You have BlackJack!") self.print_display(True) @@ -119,7 +119,7 @@ def player_play(self): def dealer_play(self): while self.dealer.get_hand_value() < 17: - self.dealer.add_card(self.draw()) + self.dealer.add_card(self.deal()) if self.dealer.has_blackjack(): self.add_message("Dealer has BlackJack.") self.print_display(True) @@ -128,26 +128,44 @@ def dealer_play(self): self.add_message("Dealer is busted!") self.print_display(True) break + self.print_display(True) def play(self): if self.player_play(): self.dealer_play() - if dealer.has_blackjack() and player.has_blackjack(): + if self.dealer.get_hand_value() == self.player.get_hand_value(): self.add_message("The round is a push.") self.print_display(True) - return False - elif player.has_blackjack(): - self.add_message("You have BlackJack!") + elif self.dealer.is_busted() or self.player.has_blackjack(): self.add_message("You win the hand!") self.print_display(True) - self.add_message("You won {}.".format(bet)) - self.player.add_score(bet) + self.add_message("You won {}.".format(self.pot)) + self.player.add_score(self.bet) self.bet = 0 self.print_display(True) - return False - elif dealer.has_blackjack(): - self.add_message("Dealer has BlackJack.") + elif self.dealer.has_blackjack() or self.player.is_busted(): self.add_message("You lose the hand.") self.print_display(True) + print("I am here") self.bet = 0 - return False + elif self.player.get_hand_value() > self.dealer.get_hand_value(): + self.add_message("You win the hand!") + self.print_display(True) + self.add_message("You won {}.".format(self.bet)) + self.player.add_score(self.bet) + self.bet = 0 + self.print_display(True) + else: + self.add_message("You lose the hand.") + self.print_display(True) + self.bet = 0 + return (self.get_input("hand") == "y") + + def run(self): + while self.start_round(): + if self.player.score < 10: + self.add_message("You don't have enough money to continue.") + self.add_message("Thank you for playing.") + self.print_display(True) + return False + return True diff --git a/blackjack/hand.py b/blackjack/hand.py index 7eb13c9..4eb756b 100644 --- a/blackjack/hand.py +++ b/blackjack/hand.py @@ -1,3 +1,6 @@ +from card import Card + + class Hand(): def __init__(self): self._card_list = [] @@ -8,9 +11,13 @@ def __init__(self): @property def card_list(self): - return self._card_list + return [card for card in self._card_list] - def get_score(self): + def get_score(self, hidden=False): + for card in self.card_list: + print(card) + if hidden: + return 0 return sum([card.value for card in self.card_list]) def start_card_value(self, rank): @@ -39,16 +46,14 @@ def evaluate_score(self): def add_card(self, card): card.value = self.start_card_value(card.rank) - card.__str__ = lambda self: "{} of {} is worth {}".format( - self.rank.title(), self.suit.title(), self.value) + print(card.value) self._card_list.append(card) self.evaluate_score() - def card_list_display(self, show_all=True): + def card_list_display(self, hidden=False): card_list = self.card_list - if not show_all: + if hidden and card_list: card_list[0] = Card("Cards", "Unknown") - card_list[0].value = 0 return ", ".join(map(str, card_list)) if __name__ == "__main__": diff --git a/blackjack/main.py b/blackjack/main.py new file mode 100644 index 0000000..2111265 --- /dev/null +++ b/blackjack/main.py @@ -0,0 +1,5 @@ +from game import Game + + +game = Game() +game.run() diff --git a/blackjack/player.py b/blackjack/player.py index bc9c5c7..218fcac 100644 --- a/blackjack/player.py +++ b/blackjack/player.py @@ -6,22 +6,22 @@ def __init__(self): self.score = 100 def start_game(self): - self.deck = Hand() + self.hand = Hand() def end_game(self): pass def add_card(self, card): - self.deck.add_card(card) + self.hand.add_card(card) def is_busted(self): - return self.deck.busted + return self.hand.busted def has_blackjack(self): - return self.deck.blackjack + return self.hand.blackjack def has_soft_hand(self): - return self.deck.soft + return self.hand.soft def bet(self, amount=10): self.score -= amount @@ -31,8 +31,7 @@ def add_score(self, amount): self.score += amount def get_hand_value(self): - return self.hand. + return self.hand.get_score(False) - @property def display_hand(self): - return self.hand.card_list_display() + return self.hand.card_list_display(False) From ec9418b17279b98993bf254cb74ad085e440118f Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Thu, 4 Jun 2015 08:38:03 -0400 Subject: [PATCH 18/22] squashed bugs --- blackjack/dealer.py | 18 +++++++--- blackjack/game.py | 81 ++++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 47 deletions(-) diff --git a/blackjack/dealer.py b/blackjack/dealer.py index c9da499..af0d0b2 100644 --- a/blackjack/dealer.py +++ b/blackjack/dealer.py @@ -1,12 +1,13 @@ from player import Player +from hand import Hand class Dealer(Player): def __init__(self): - pass + self.hidden = True - def display_hand(self, hidden=False): - return self.hand.card_list_display(hidden) + def display_hand(self): + return self.hand.card_list_display(self.hidden) def bet(self): pass @@ -14,5 +15,12 @@ def bet(self): def add_score(self): pass - def get_hand_value(self, hidden=False): - return self.hand.get_score(hidden) + def get_hand_value(self): + return self.hand.get_score(self.hidden) + + def start_game(self): + self.hidden = True + self.hand = Hand() + + def start_turn(self): + self.hidden = False diff --git a/blackjack/game.py b/blackjack/game.py index 33c9298..0f80e75 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -18,8 +18,8 @@ def print_display(self, wait=False): self.get_continue() def update_display(self, hidden=True): - display_list = ["Dealer:", self.dealer.display_hand(hidden), - "Score: " + str(self.dealer.get_hand_value(hidden)) + + display_list = ["Dealer:", self.dealer.display_hand(), + "Score: " + str(self.dealer.get_hand_value()) + " | Pot: " + str(self.pot), "- "*20, "You:", self.player.display_hand(), "Score: " + str(self.player.get_hand_value()) + @@ -32,28 +32,20 @@ def start_round(self): self.pot = self.player.bet(self.get_bet_input()) self.player.start_game() self.dealer.start_game() - self.add_message("Welcome to BlackJack!") + self.add_message("Welcome to Blackjack!") self.get_continue() self.initial_deal() if self.dealer.has_blackjack() and self.player.has_blackjack(): - self.add_message("The round is a push.") - self.print_display(True) - return False + self.dealer.hidden = False + self.push("Both dealer and player have Blackjack.") + return self.get_input("hand") elif self.player.has_blackjack(): - self.add_message("You have BlackJack!") - self.add_message("You win the hand!") - self.print_display(True) - self.add_message("You won {}.".format(self.bet)) - self.player.add_score(self.bet) - self.bet = 0 - self.print_display(True) - return False + self.player_wins("You have Blackjack!") + return self.get_input("hand") elif self.dealer.has_blackjack(): - self.add_message("Dealer has BlackJack.") - self.add_message("You lose the hand.") - self.print_display(True) - self.bet = 0 - return False + self.dealer.hidden = False + self.dealer_wins("Dealer has Blackjack.") + return self.get_input("hand") return self.play() def initial_deal(self): @@ -108,7 +100,7 @@ def player_play(self): while self.get_input("choice") == "hit": self.player.add_card(self.deal()) if self.player.has_blackjack(): - self.add_message("You have BlackJack!") + self.add_message("You have Blackjack!") self.print_display(True) return True elif self.player.is_busted(): @@ -118,10 +110,11 @@ def player_play(self): return True def dealer_play(self): + self.dealer.start_turn() while self.dealer.get_hand_value() < 17: self.dealer.add_card(self.deal()) if self.dealer.has_blackjack(): - self.add_message("Dealer has BlackJack.") + self.add_message("Dealer has Blackjack.") self.print_display(True) break if self.dealer.is_busted(): @@ -134,31 +127,15 @@ def play(self): if self.player_play(): self.dealer_play() if self.dealer.get_hand_value() == self.player.get_hand_value(): - self.add_message("The round is a push.") - self.print_display(True) + self.push() elif self.dealer.is_busted() or self.player.has_blackjack(): - self.add_message("You win the hand!") - self.print_display(True) - self.add_message("You won {}.".format(self.pot)) - self.player.add_score(self.bet) - self.bet = 0 - self.print_display(True) + self.player_wins() elif self.dealer.has_blackjack() or self.player.is_busted(): - self.add_message("You lose the hand.") - self.print_display(True) - print("I am here") - self.bet = 0 + self.dealer_wins() elif self.player.get_hand_value() > self.dealer.get_hand_value(): - self.add_message("You win the hand!") - self.print_display(True) - self.add_message("You won {}.".format(self.bet)) - self.player.add_score(self.bet) - self.bet = 0 - self.print_display(True) + self.player_wins() else: - self.add_message("You lose the hand.") - self.print_display(True) - self.bet = 0 + self.dealer_wins() return (self.get_input("hand") == "y") def run(self): @@ -169,3 +146,23 @@ def run(self): self.print_display(True) return False return True + + def player_wins(self, message=""): + self.add_message(message) + self.add_message("You win the hand!") + self.print_display(True) + self.add_message("You won {}!".format(self.pot * 2)) + self.player.add_score(self.pot * 2) + self.pot = 0 + self.print_display(True) + + def dealer_wins(self, message=""): + self.add_message(message) + self.add_message("You lose the hand.") + self.print_display(True) + self.pot = 0 + + def push(self, message=""): + self.add_message(message) + self.add_message("The round is a push.") + self.print_display(True) From cf6b47a487c01201f6b4d5e9726beb2ae04abaed Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Thu, 4 Jun 2015 08:42:57 -0400 Subject: [PATCH 19/22] fixed dealer hit before displaying hidden card --- blackjack/game.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/blackjack/game.py b/blackjack/game.py index 0f80e75..fd0f948 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -8,7 +8,7 @@ class Game(): def __init__(self): self.player = Player() self.dealer = Dealer() - self.display = Display(7) + self.display = Display(8) self.pot = 0 def print_display(self, wait=False): @@ -111,6 +111,7 @@ def player_play(self): def dealer_play(self): self.dealer.start_turn() + self.print_display(True) while self.dealer.get_hand_value() < 17: self.dealer.add_card(self.deal()) if self.dealer.has_blackjack(): From 6f22b9b0a5443a1ad9cf8569ba40a30bf2aa3529 Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Thu, 4 Jun 2015 09:02:54 -0400 Subject: [PATCH 20/22] if round_result functions don't receive a message, they will no longer print a blank line --- blackjack/game.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/blackjack/game.py b/blackjack/game.py index fd0f948..c5bca2b 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -149,21 +149,27 @@ def run(self): return True def player_wins(self, message=""): - self.add_message(message) + if message: + self.add_message(message) self.add_message("You win the hand!") self.print_display(True) - self.add_message("You won {}!".format(self.pot * 2)) - self.player.add_score(self.pot * 2) + pot_multiplier = 2 + if self.player.has_blackjack(): + pot_multiplier = 3 + self.add_message("You won {}!".format(self.pot * pot_multiplier)) + self.player.add_score(self.pot * pot_multiplier) self.pot = 0 self.print_display(True) def dealer_wins(self, message=""): - self.add_message(message) + if message: + self.add_message(message) self.add_message("You lose the hand.") self.print_display(True) self.pot = 0 def push(self, message=""): - self.add_message(message) + if message: + self.add_message(message) self.add_message("The round is a push.") self.print_display(True) From d3f8c4108989413f94fb83b8c0d6460fde1e83cf Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Sun, 7 Jun 2015 18:10:19 -0400 Subject: [PATCH 21/22] now allow the player to choose how much to bet. Also tweaked messages having to do with money --- blackjack/game.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/blackjack/game.py b/blackjack/game.py index c5bca2b..8a362b5 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -29,11 +29,11 @@ def update_display(self, hidden=True): def start_round(self): self.deck = Deck() - self.pot = self.player.bet(self.get_bet_input()) self.player.start_game() self.dealer.start_game() self.add_message("Welcome to Blackjack!") - self.get_continue() + self.print_display(True) + self.pot = self.player.bet(self.get_input("bet")) self.initial_deal() if self.dealer.has_blackjack() and self.player.has_blackjack(): self.dealer.hidden = False @@ -65,6 +65,8 @@ def get_input(self, type): return self.get_stand_or_hit() def get_hand_input(self): + if not self.enough_money(): + return False while True: string = "Do you want to play another hand? (y/n) > " value = input(string).lower() @@ -74,9 +76,16 @@ def get_hand_input(self): self.print_display() def get_bet_input(self): - # return input("How much do you want to bet?") - self.add_message("Betting 10.") - return 10 + while True: + bet = input("How much do you want to bet? > ") + if bet.isdigit() and bet != "0": + if int(bet) > self.player.score: + self.add_message("You don't have that much.") + self.print_display() + continue + return int(bet) + self.add_message("Please enter a positive integer.") + self.print_display() def get_stand_or_hit(self): while True: @@ -113,6 +122,7 @@ def dealer_play(self): self.dealer.start_turn() self.print_display(True) while self.dealer.get_hand_value() < 17: + self.add_message("Dealer hits.") self.dealer.add_card(self.deal()) if self.dealer.has_blackjack(): self.add_message("Dealer has Blackjack.") @@ -123,6 +133,8 @@ def dealer_play(self): self.print_display(True) break self.print_display(True) + self.add_message("Dealer stands.") + self.print_display(True) def play(self): if self.player_play(): @@ -141,11 +153,7 @@ def play(self): def run(self): while self.start_round(): - if self.player.score < 10: - self.add_message("You don't have enough money to continue.") - self.add_message("Thank you for playing.") - self.print_display(True) - return False + pass return True def player_wins(self, message=""): @@ -173,3 +181,11 @@ def push(self, message=""): self.add_message(message) self.add_message("The round is a push.") self.print_display(True) + + def enough_money(self): + if self.player.score < 1: + self.add_message("You don't have enough money to continue.") + self.add_message("Thank you for playing.") + self.print_display(True) + return False + return True From afded7d1d6236232a5ad9899b6d3e5bf54a512df Mon Sep 17 00:00:00 2001 From: PJ Passalacqua Date: Sun, 7 Jun 2015 18:28:40 -0400 Subject: [PATCH 22/22] removed unecessary prints from hand; added doubling down --- blackjack/game.py | 50 +++++++++++++++++++++++++++++++++-------------- blackjack/hand.py | 3 --- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/blackjack/game.py b/blackjack/game.py index 8a362b5..7253a98 100644 --- a/blackjack/game.py +++ b/blackjack/game.py @@ -89,11 +89,11 @@ def get_bet_input(self): def get_stand_or_hit(self): while True: - string = "Do you want to stand or hit? > " + string = "Do you want to stand, hit, or double down? > " value = input(string).lower() - if value in ("stand", "hit"): + if value in ("stand", "hit", "double down"): return value - self.add_message("Please enter 'stand' or 'hit'") + self.add_message("Please enter 'stand', 'hit', or 'double down'.") self.print_display() def add_message(self, message): @@ -106,17 +106,37 @@ def deal(self): return self.deck.draw() def player_play(self): - while self.get_input("choice") == "hit": - self.player.add_card(self.deal()) - if self.player.has_blackjack(): - self.add_message("You have Blackjack!") - self.print_display(True) - return True - elif self.player.is_busted(): - self.add_message("You have busted.") + while True: + choice = self.get_input("choice") + if choice == "hit": + self.player.add_card(self.deal()) + if self.player.has_blackjack(): + self.add_message("You have Blackjack!") + self.print_display(True) + return True + elif self.player.is_busted(): + self.add_message("You have busted.") + self.print_display(True) + return False + continue + if choice == "double down": + if self.player.score < self.pot: + self.add_message("You don't have enough money.") + self.print_display(True) + continue + self.add_message("Doubling down.") + self.pot += self.player.bet(self.pot) self.print_display(True) - return False - return True + self.player.add_card(self.deal()) + if self.player.has_blackjack(): + self.add_message("You have Blackjack!") + self.print_display(True) + return True + elif self.player.is_busted(): + self.add_message("You have busted.") + self.print_display(True) + return False + return True def dealer_play(self): self.dealer.start_turn() @@ -127,11 +147,11 @@ def dealer_play(self): if self.dealer.has_blackjack(): self.add_message("Dealer has Blackjack.") self.print_display(True) - break + return if self.dealer.is_busted(): self.add_message("Dealer is busted!") self.print_display(True) - break + return self.print_display(True) self.add_message("Dealer stands.") self.print_display(True) diff --git a/blackjack/hand.py b/blackjack/hand.py index 4eb756b..ad9512f 100644 --- a/blackjack/hand.py +++ b/blackjack/hand.py @@ -14,8 +14,6 @@ def card_list(self): return [card for card in self._card_list] def get_score(self, hidden=False): - for card in self.card_list: - print(card) if hidden: return 0 return sum([card.value for card in self.card_list]) @@ -46,7 +44,6 @@ def evaluate_score(self): def add_card(self, card): card.value = self.start_card_value(card.rank) - print(card.value) self._card_list.append(card) self.evaluate_score()