The Game class and main loop

We will define the game's main loop within the class __init__ method so that to begin playing, we simply need to create an instance of this class:

class Game:
def __init__(self):
playing = True

while playing:
self.deck = Deck()
self.deck.shuffle()

self.player_hand = Hand()
self.dealer_hand = Hand(dealer=True)

for i in range(2):
self.player_hand.add_card(self.deck.deal())
self.dealer_hand.add_card(self.deck.deal())

print("Your hand is:")
self.player_hand.display()
print()
print("Dealer's hand is:")
self.dealer_hand.display()

We start off our loop with a Boolean which will be used to track whether or not we are still playing the game.

If we are, we need a shuffled Deck and two Hand instances—one for the dealer and one for the player.

We use the range function to deal two cards each to the player and the dealer. Our deal method will return a Card instance, which is passed to the add_card method of our Hand instances.

We now want to display the hands to our player. We can use the display method on our Hand instances to print this to the screen.

This marks the end of the code which needs to run at the beginning of every new game. Now we enter a loop which will run until a winner is decided. We again control this with a Boolean:

game_over = False

while not game_over:
player_has_blackjack, dealer_has_blackjack = self.check_for_blackjack()

We first need to check for blackjack. If either player has been dealt an ace and a picture card, their hand will total 21, so they automatically win. Let's jump to the function which does this:

def check_for_blackjack(self):
player = False
dealer = False
if self.player_hand.get_value() == 21:
player = True
if self.dealer_hand.get_value() == 21:
dealer = True

return player, dealer

We need to keep track of which player may have blackjack, so we will keep a Boolean for the player and dealer.

Next, we need to check whether either's hand totals 21, which we will do using two if statements. If either has a hand value of 21, their Boolean is changed to True.

If either of the Booleans are True, then we have a winner, and will print the winner to the screen and continue, thus breaking us out of the game loop:

if player_has_blackjack or dealer_has_blackjack:
game_over = True
self.show_blackjack_results(player_has_blackjack, dealer_has_blackjack)
continue

To print the winner to the screen, we have another function named show_blackjack_results which will handle displaying the correct winner:

    def show_blackjack_results(self, player_has_blackjack, 
dealer_has_blackjack):
if player_has_blackjack and dealer_has_blackjack:
print("Both players have blackjack! Draw!")

elif player_has_blackjack:
print("You have blackjack! You win!")

elif dealer_has_blackjack:
print("Dealer has blackjack! Dealer wins!")

If neither player had blackjack, the game loop will continue.

The player can now make a choice—whether or not to add more cards to their hand (hit) or submit their current hand (stick):

choice = input("Please choose [Hit / Stick] ").lower()
while choice not in ["h", "s", "hit", "stick"]:
choice = input("Please enter 'hit' or 'stick' (or H/S) ").lower()

We use the input function to collect a choice from the user. This will always return us a string containing the text the user typed into the command line.

If you are following along with Python 2, make sure to use raw_input in place of input. In Python 2, input will try and evaluate what is typed in, which is not what we need here.

Since we have a string, we can cast the user's input to lowercase using the lower function to avoid having to check combinations of upper case and lower case when parsing their reply.

If their input is not recognized, we will simply keep asking for it again until it is:

if choice in ['hit', 'h']:
self.player_hand.add_card(self.deck.deal())
self.player_hand.display()

Should the player choose to hit, they will need to add an extra card to their hand. This is done in the same way as before—using deal() and add_card().

Since their total has changed, we will now need to check whether they are over the allowed limit of 21. We'll jump to a function which does this now:

def player_is_over(self):
return self.player_hand.get_value() > 21

This simple function merely checks whether the player's hand value is over 21 and returns the information as a Boolean. Nothing too complicated here. Back to our main loop:

if self.player_is_over():
print("You have lost!")
has_won = True

If the player’s hand has a value over 21, they have lost, so the game loop needs to break and we set has_won to True (indicating that the dealer has won).

When the player decides to stick with their hand, it is time for their score to be compared with the dealer's:

else:
print("Final Results")
print("Your hand:", self.player_hand.get_value())
print("Dealer's hand:", self.dealer_hand.get_value())

if self.player_hand.get_value() > self.dealer_hand.get_value():
print("You Win!")
else:
print("Dealer Wins!")
has_won = True

We use the else statement here because we have already established that the user's answer was either hit or stick, and we have just checked hit. This means we will only get into this block when the user answers stick.

The value of both the player's and the dealer's hand are printed to the screen to give the final results. We then compare the values of each hand to see which is higher.

If the player's hand is a higher value than the dealer's, we print You Win!. If the scores are equal, then we have a tie, so we print Tie!. Otherwise, the dealer must have a higher hand than the player, so we show Dealer wins!:

again = input("Play Again? [Y/N] ")
while again.lower() not in ["y", "n"]:
again = input("Please enter Y or N ")
if again.lower() == "n":
print("Thanks for playing!")
playing = False
else:
has_won = False

Outside of our while loop, we check whether the user wishes to play again.

We once again use the combination of lower and a while loop to ensure our answer is a y or n.

If the player answers with n, we thank them for playing and set our playing Boolean to False, thus breaking us out of the main game loop and ending the program.

If not, they must have answered y, so we set has_won to False and let our main loop run again. This will take us right back to the top at self.deck = Deck() to set up a brand new game.

To run this code, we simply create an instance of the Game class:

if __name__ == "__main__":
game = Game()

Now we have a game, give it a play. While playing, be sure you can follow exactly where you are in the game's main loop.

This version of blackjack is kept simple in order to give us a command-line application which we can now convert to a GUI-based game. The dealer will never hit and there is no concept of betting. Feel free to try and add these features yourself if you wish, or carry on with the next chapter, where we will begin to add graphics by going back over to the Tkinter library.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset