Search code examples
pythonblackjack

Blackjack python script, flow error when restarting game


I am a Python newbie but I tried my hand at writing a blackjack script. After debugging and correcting all the obvious errors, I am coming across a strange incident that I can't figure out.

When the total is >21, it seems to skip past the while (total < 21) and (stand != True): block of code, even though at the beginning of the game loop I zero out all of the relevant variables.

I've spent way too much time trying to figure this out, and I can't help but think this has an obvious solution.

I don't understand why while (total < 21) and (stand != True): seems to be skipped even though it should be a true statement at the beginning of every game.

Here is the full code below. Feel free to test it yourselves to see what I mean.

import pygame
import random

print("Welcome to PyBlackjack V1.0")
done =  False

while not done:

    # --- Reset our Hands ---

    dealerhand = 0
    split = False
    stand = False
    total = 0

    # --- Dealing the Player's hand. ---

    print("Dealer is dealing hand.")
    firstcard = random.randrange(1, 15)
    print("First card:",str(firstcard),)
    secondcard = random.randrange(1, 15)
    print("Second card:",str(secondcard),)

    total = (firstcard + secondcard)

    print("Hand:",str(total),)

        # --- Bust Check ---

    if total > 21:
        print("Bust! Game Over.")
        newgame = input("Play again? Y/N: ")
        if str(newgame) == "n":
            done = True
            break
        else:
            print("Starting new game! Good Luck!")

    dealerfirstcard = random.randrange(1, 15)
    dealerholecard = random.randrange(1, 15)

    dealerhand = (dealerfirstcard + dealerholecard)

    print("Dealer's Hand:",str(dealerfirstcard))

    # --- Player decides what to do ---

    while (total < 21) and (stand != True):

        if split != True:
            print("Hand:",str(total))
        elif split == True:
            print("Left hand:",str(lefthand),"| Right hand:",str(righthand))

        playerchoice = input("Hit (1), Double Down(2), Split(3), Stand(4)?")

        if int(playerchoice) == 1:
            total += random.randrange(1, 15)
        elif int(playerchoice) == 2:
            #Reserved
            break
        elif int(playerchoice) == 3:
            if ((firstcard + secondcard) / 2) == firstcard and split != True:
                lefthand = (firstcard + random.randrange(1, 15))
                righthand = (secondcard + random.randrange(1, 15))
                split = True
            else:
                print("You cannot split this hand!")
        elif int(playerchoice) == 4:
            print("You stand.")
            stand = True
        else:
            print("Invalid Choice!")

    print("Hand:",total,)

    if total > 21:
        print("Bust! Game Over.")

    newgame = input("Play again? Y/N: ")
    if str(newgame) == "n":
        done = True
        break
    else:
        print("Starting new game! Good Luck!")

    print("Dealer reveals hole card...")
    print("Dealer Hand:",str(dealerhand),)

    # --- Dealer hits until >= 17 ---

    while dealerhand < 17:
        print("Dealer hits...")
        dealerhand = (dealerhand + random.randrange(1, 15))
        print("Dealer hand:",dealerhand,)

    # --- Deciding who wins ---

    if dealerhand > 21:
        print("Dealer busts! You win!")
    elif dealerhand >= 17:
        print("Your hand:",total,"| Dealer hand:",dealerhand,)
        if split != True:
            if dealerhand >= total:
                print("You lose!")
            elif dealerhand < total:
                print("You win!")
        elif split == True:
            if lefthand > dealerhand:
                print("Left hand wins!")
            elif lefthand < dealerhand:
                print("Left hand loses!")
            else:
                print("An error occured. Ending program.")
                done = True
                break

            if righthand > dealerhand:
                print("Right hand wins!")
            elif righthand < dealerhand:
                print("Right hand loses!")
            else:
                print("An error occured. Ending program.")
                done = True
                break

    # --- To loop or not to loop ---

    newgame = input("Play again? Y/N: ")
    if str(newgame) == "n":
        done = True
        break
    else:
        print("Starting new game! Good Luck!")

Solution

  • Below is (sort of) working code. It still implements an odd variant of Blackjack (ranks go from 1 to 15, no such thing as an ace that counts as either 1 or 11, split is allowed after hitting). Splitting in general is not well handled here... I think you can split and then still hit/etc.? But hitting doesn't update either of the split hands, and splitting again doesn't do anything. I'll leave it to you to sort out those logical errors.

    I think the issue you're describing is explained best by @Martin's answer. I ended up just simplifying this logic with an else to handle the non-bust case. Incidentally, there's no need to use flags like stand or done to exit a loop if what you really want is to just break.

    I also cleaned up some miscellaneous things... dropped some unnecessary conversions to str, cleaned up the logic of detecting a player bust, detecting and printed pushes, etc. See the full code below and pay attention to the differences.

    import random
    
    print("Welcome to PyBlackjack V1.0")
    
    while True:
        # --- Reset our Hands ---
        dealerhand = 0
        split = False
        total = 0
    
        # --- Dealing the Player's hand. ---
        print("Dealer is dealing hand.")
        firstcard = random.randrange(1, 15)
        print("First card:", firstcard)
        secondcard = random.randrange(1, 15)
        print("Second card:", secondcard)
    
        total = firstcard + secondcard
    
        print("Hand:", total)
    
        dealerfirstcard = random.randrange(1, 15)
        dealerholecard = random.randrange(1, 15)
    
        dealerhand = dealerfirstcard + dealerholecard
    
        print("Dealer's hole card:", dealerfirstcard)
    
        # --- Player decides what to do ---
        while total < 21:
            if not split:
                print("Hand:", total)
            else:
                print("Left hand:", lefthand, "| Right hand:", righthand)
    
            playerchoice = int(input("Hit (1), Double Down(2), Split(3), Stand(4)? "))
    
            if playerchoice == 1:
                total += random.randrange(1, 15)
            elif playerchoice == 2:
                #Reserved
                break
            elif playerchoice == 3:
                # NOTE: This will allow splitting even after hitting
                if firstcard == secondcard and not split:
                    lefthand = firstcard + random.randrange(1, 15)
                    righthand = secondcard + random.randrange(1, 15)
                    split = True
                else:
                    print("You cannot split this hand!")
            elif playerchoice == 4:
                print("You stand.")
                break
            else:
                print("Invalid Choice!")
    
        print("Hand:", total)
    
        if total > 21:
            print("Bust! Game Over.")
        else:
            print("Dealer reveals hole card...")
            print("Dealer hand:", dealerhand)
    
            # --- Dealer hits until >= 17 ---
            while dealerhand < 17:
                print("Dealer hits...")
                dealerhand += random.randrange(1, 15)
                print("Dealer hand:", dealerhand)
    
            # --- Deciding who wins ---
            if dealerhand > 21:
                print("Dealer busts! You win!")
            else:
                print("Your hand:", total, "| Dealer hand:", dealerhand)
                if not split:
                    if dealerhand >= total:
                        print("You lose!")
                    elif dealerhand < total:
                        print("You win!")
                    else:
                        print("Push.")
                else:
                    if lefthand > dealerhand:
                        print("Left hand wins!")
                    elif lefthand < dealerhand:
                        print("Left hand loses!")
                    else:
                        print("Push.")
    
                    if righthand > dealerhand:
                        print("Right hand wins!")
                    elif righthand < dealerhand:
                        print("Right hand loses!")
                    else:
                        print("Push.")
    
        # --- To loop or not to loop ---
        newgame = input("Play again? Y/N: ")
        if str(newgame) == "n":
            break
        else:
            print("Starting new game! Good Luck!")