2
\$\begingroup\$

I've noticed I'm not the first to post this topic. As a matter of fact, I have taken some inspiration from Victor Nguyen Bao's post to help structure my code. Here's the link to his code: Structured blackjack game in Python 3

The other source of my code is from Anthony Tapias. https://medium.com/@anthonytapias/build-a-deck-of-cards-with-oo-python-c41913a744d3

I began to learn python during my intro to computer science class in fall, but I felt I wasn't being challenged enough. I wanted to learn more, but at the same time, not overwhelm myself.

I found many resources thankfully, and my textbook Python Crash Course 2nd Edition has a few things going for it. We stopped right at functions. I wanted to learn more about classes, and felt overwhelmed with Alien Invasion. So, I took a step back and tried to do something more simple like Blackjack.

It turns out that this actually was quite a bit of a challenge for me! Debugging was rather tricky but it helped to use print statements to make sure certain lines of code were running as intended.

The major issue I am having with my code right now is when the player goes bust, the dealer shouldn't draw anymore cards, and instead should reveal their current hand, display that the player lost, and prompt the player if they wanted to play another game.

The other issue I seem to be having is styling my code to meet PEP8 standards. I've tried to stay consistent with the way I named my classes. Although, these classes did come from another source, the only class I created was the Dealer.

I definitely feel I could clean this code up by reorganizing some lines of code, renaming certain methods, and using better identifiers. I'm hoping to get a healthy amount of constructive criticism. I'm also hoping to be able to create another game from scratch without referencing any other code in the future. What do you all think?

blackjack_v1.py

from dealer import Dealer
from card import Card
from deck import Deck
#I commented out certain lines of code for debugging purposes.
class Blackjack:
    """Overall class to manage game assets and behavior."""

    def __init__(self):
        """Initialize the game, and create resources."""
        self.games = 0
        self.main_game_loop = True
        self.player = Player()
        self.dealer = Dealer()
        self.first_turn_new_game = False
        self.turns = False

    def run(self):
        """Begins the main loop to run the game."""
        while self.main_game_loop == True:
            deck = Deck()
            deck.shuffle()             
            self.deal_cards(deck)
            print("Your Hand:")
            self.player.blackjack_check()
            self.player.showHand()
            print("Dealer's hand:")
            self.dealer.blackjack_check()
            self.compare_first_hand()
            if(self.first_turn_new_game == True):
                self.another_game()
            else:
                self.player.turn(deck)
                self.dealer.dealer_turn(deck)
                self.compare_hands()
                self.another_game()

    def deal_cards(self, deck):
        """Deals cards to both player and dealer."""
        for i in range(0, 2):
            self.player.draw(deck)
            self.dealer.draw(deck)
        self.player.ace_check()
        self.dealer.ace_check()

    def compare_first_hand(self):
        """Compares the first hand between players."""
       # print(f"The truth value of player.blackjack is currently {self.player.blackjack == True}")
        #print(f"The turth value of dealer.blackjack is currently {self.dealer.blackjack == True}")
        if (self.player.blackjack == True) and (self.dealer.blackjack == True):
            self.dealer.showHand()
            self.player.ties += 1
            self.dealer.ties += 1
            print("The game is a tie!")           
            self.first_turn_new_game = True
        elif (self.player.blackjack == True) and (self.dealer.blackjack == False):
            self.dealer.showHand()
            self.player.wins += 1
            self.dealer.losses += 1
            print("You win!")
            #print(f"The truth value of player.blackjack should be True. It is {self.player.blackjack == True}")
            #print(f"The turth value of dealer.blackjack should be False. It is {self.dealer.blackjack == True}")
            self.first_turn_new_game = True
        elif (self.player.blackjack == False) and (self.dealer.blackjack == True):
            self.dealer.showHand()
            self.player.losses += 1
            self.dealer.wins += 1
            print("You lost!")
            #print(f"The truth value of player.blackjack should be False. It is {self.player.blackjack == True}")
            #print(f"The turth value of dealer.blackjack should be True. It is {self.dealer.blackjack == True}")
            self.first_turn_new_game = True
            #print(f"first_turn_new_game should be true. It is {self.first_turn_new_game == True}")
        else:
            self.turns = True
            #print(f"Turns should be  True. It is {self.turns == True}")
            self.dealer.show_initial_hand()

    def compare_hands(self):
        """Compares hand between players."""
        if (self.player.blackjack == True) and (self.dealer.blackjack == True):
            self.player.ties += 1
            self.dealer.ties += 1
            print("The game is a tie!")
        elif (self.player.blackjack == True) and (self.dealer.bust == False) and (self.dealer.blackjack == False):
            self.player.wins += 1
            self.dealer.losses += 1
            print("You win!")
        elif (self.player.bust == True) and (self.dealer.blackjack == True):
            self.player.losses += 1
            self.dealer.wins += 1
            print("You lost!")
        elif (self.player.bust == False) and (self.player.blackjack == False) and (self.dealer.blackjack == True):
            self.player.losses += 1
            self.dealer.wins += 1
            print("You lost!")
        elif (self.player.bust == True):
            self.player.losses += 1
            self.dealer.wins += 1
            print("You lost!")
        elif (self.dealer.bust == True) and (self.player.bust == False) and (self.player.blackjack == False):
            self.player.wins += 1
            self.dealer.losses += 1
            print("You win!")
        else:
            player_hand = []
            dealer_hand = []
            for card in self.player.hand:
                player_hand.append(card.face_value)
            for card in self.dealer.hand:
                dealer_hand.append(card.face_value)
            if sum(player_hand) > sum(dealer_hand):
                self.player.wins += 1
                self.dealer.losses += 1
                print("You win!")
            elif sum(player_hand) == sum(dealer_hand):
                self.player.ties += 1
                self.dealer.ties += 1
                print("The game is a tie!")           
            elif sum(player_hand) < sum(dealer_hand):
                self.player.losses += 1
                self.dealer.wins += 1
                print("You lost!")

    def reset_variables(self):
        """Resets all variables to set up for the next game."""
        for p in [self.player, self.dealer]:
            p.hand = []
            #print("The length of {} hand is {}".format(p, len(p.hand)))
            p.blackjack = False
            #print("The truth value of blackjack for {} should be False. This statement is {}".format(p, p.blackjack == False))
            p.bust = False
            #print("The truth value of bust for {} should be False. This statement is {}".format(p, p.bust == False))
            p.stand = False
            #print("The truth value of stand for {} should be False. This statement is {}".format(p, p.stand == False))
        self.first_turn_new_game = False
        #print("The truth value of first_turn_new_game for {} should be False. This statement is {}".format(self, self.first_turn_new_game == False))
        self.turns = False
        #print("The truth value of turns should be False. This statement is {}".format(self.turns == False))

    def final_results(self):
        """Display the overall end results across all games."""
        print("Final results:")
        print("Your wins: {} | Your losses: {} Ties {}".format(self.player.wins, self.player.losses, self.player.ties))
        print("Thank you for playing!")

    def another_game(self):
        """Asks user if they would like to play again. Resets game."""
        while(True):
            play_again_yes_options = ["yes", "YES", "Yes", "Y", "y"]
            play_again_no_options = ["no", "NO", "No", "N", "n"]
            play_again = input("Would you like to play again? Yes or No: ")
            if play_again in play_again_yes_options:
                self.reset_variables()
                break
            elif play_again in play_again_no_options:
                self.final_results()
                self.main_game_loop = False
                break
            else:
                print(f"{play_again} is not a valid response.")
if __name__ == '__main__':
    game = Blackjack()
    game.run()

dealer.py

from player import Player
class Dealer(Player):
    """Model of dealer AI."""

    def __init__(self):
        """Initialize attributes of the parent class"""
        super().__init__()

    def show_initial_hand(self):
        """Shows first hand."""
        self.hand[0].show_card()
        print(f"The value of the Dealer's face-up card is: {self.hand[0].face_value}")

    def dealer_turn(self, deck):
        """Dealer's actions during the game."""
        check_list_17 = []
        for card in self.hand:
            check_list_17.append(card.face_value)
        while sum(check_list_17) < 17:
            self.draw(deck)
            self.ace_check()
            self.blackjack_check()
            check_list_17.append(self.hand[-1].face_value)
        print("Dealer hand: ")
        self.showHand()

player.py

class Player:
    """Model of a user."""

    def __init__(self):
        """Initializes attributes of a player."""
        self.hand = []
        self.wins = 0
        self.losses = 0
        self.ties = 0
        self.blackjack = False
        self.bust = False
        self.stand = False

    def turn(self, deck):
        """Player's initial hand."""
        hit_options = ["H", "h", "HIT", "Hit", "hit", "Hit me", "hit me"]
        stand_options = ["S", "s", "STAND", "Stand", "stand"]
        while(self.stand == False) and (self.bust == False) and (self.blackjack == False):
            hit_or_stand = input("Hit or Stand?: \n")
            if hit_or_stand in hit_options:
                self.draw(deck)
                self.ace_check()
                self.blackjack_check()
                print("Your current hand is:")
                self.showHand()
            elif hit_or_stand in stand_options:
                self.stand = True
                break
            else:
                print(f"'{hit_or_stand}' is not a valid response.")

    def draw(self, deck):
        """Draws card and appends the card to hand."""
        self.hand.append(deck.drawCard())

    def showHand(self):
        for card in self.hand:
            card.show_card()
        player_hand_total_check = []
        for card in self.hand:
            player_hand_total_check.append(card.face_value)
        PLAYER_HAND_TOTAL = sum(player_hand_total_check)
        print(f"The total of the hand is: {PLAYER_HAND_TOTAL}")

    def ace_check(self):
        """Check's for ace in hand and evaluates to appropriate face value."""
        hand_ace_check_list = []
        number_of_cards_in_hand = len(self.hand)
        for card in self.hand:
            hand_ace_check_list.append(card.face_value)
        hand_check_TOTAL = sum(hand_ace_check_list)
        if 11 in hand_ace_check_list and hand_check_TOTAL > 21:
            count = 0
            for card in self.hand:
                if card.face_value == 11:
                    card.face_value = 1
                if hand_ace_check_list[count] == 11:
                    hand_ace_check_list[count] = 1
                if sum(hand_ace_check_list) <= 21:
                    break
                count += 1

    def blackjack_check(self):
        """Check's hand for blackjack or bust."""
        hand_list = []
        for card in self.hand:
            hand_list.append(card.face_value)
        if sum(hand_list) == 21:
            self.blackjack = True
        elif sum(hand_list) > 21:
            self.bust = True

card.py

class Card:
    """Model of a playing card."""

    def __init__(self, rank, face_value, suit):
        """Initializes attributes of a card."""
    
        self.rank = rank
        self.face_value = face_value
        self.suit = suit

    def show_card(self):
        """Reveals the rank and suit of card."""
        if self.rank == 1:
            print("{} of {}, valued at {}".format("Ace", self.suit, self.face_value))
        elif self.rank == 11:
            print("{} of {}".format("Jack", self.suit))
        elif self.rank == 12:
            print("{} of {}".format("Queen", self.suit))
        elif self.rank == 13:
            print("{} of {}".format("King", self.suit))
        else:
            print("{} of {}".format(self.rank, self.suit))

deck.py

from random import randint
from card import Card
class Deck:
    """Model of a deck of 1-8 decks of playing cards, with 52 cards per deck."""

    def __init__(self):
        """Initializes attributes of a deck."""
        self.cards = []
        self.build()

    def build(self):
        """Creates a deck of cards."""
        face_cards_ranks = [11, 12, 13]
        for i in range(0,8):
            for s in ["Clubs", "Diamonds", "Spades", "Hearts"]:
                for r in range(1, 14):
                    if r == 1:
                        face = 11
                        self.cards.append(Card(r, face, s))
                    elif r in face_cards_ranks:
                        face = 10
                        self.cards.append(Card(r, face, s))
                    else:
                        face = r
                        self.cards.append(Card(r, face, s))

    def shuffle(self):
        """Shuffles cards using the Fisher Yates shuffle"""
        for i in range(len(self.cards) - 1, 0, -1):
            r = randint(0, i)
            self.cards[i], self.cards[r] = self.cards[r], self.cards[i]

    def drawCard(self):
        """Draws a card from the deck"""
        return self.cards.pop()

    def show(self):
        """Shows every card in the deck."""
        for c in self.cards:
            c.show_card()
```
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.