Lamar
Lamar

Reputation: 217

python blackjack ace problem which breaks my code

I currently am making a blackjack python minigame, where a player plays until he gets a blackjack or stands and returns the value of his deck. This game does not play against a dealer and instead just uses his hands as a score. My problem is, I cannot figure out a way to make aces go from 11 to 1 without looping and breaking the program. Here is my code:

   import random


def play():
    output = "Your hand: "
    player = []
    total=0
    count = 0
    while len(player) != 2:
        card = random.randint(1,52)
        if card <= 4:
            output += "A "
            total += 11
            player.append("A")
        elif card <= 8:
            output+="2 "
            total+=2
            player.append("2")
        elif card <= 12:
            output+="3 "
            total+=3
            player.append("3")
        elif card <= 16:
            output+="4 "
            total+=4
            player.append("4")
        elif card <= 20:
            output+="5 "
            total+=5
            player.append("5")
        elif card <= 24:
            output+="6 "
            total+=6
            player.append("6")
        elif card <= 28:
            output+="7 "
            total+=7
            player.append("7")
        elif card <= 32:
            output+="8 "
            total+=8
            player.append("8")
        elif card <= 36:
            output+="9 "
            total+=9
            player.append("9")
        elif card <= 40:
            output+="10 "
            total+=10
            player.append("10")
        elif card <= 44:
            output+="J "
            total+=10
            player.append("J")
        elif card <= 48:
            output+="Q "
            total+=10
            player.append("Q")
        elif card <= 52:
            output+= "K "
            total+=10
            player.append("K")
        if len(player) == 2:
            print(f"{output} ({total}) ")

    while len(player) >= 2:
        action_taken = input("Would you like to 'hit' or 'stand': ")
        if action_taken == "hit":
            card = random.randint(1,52)
            if card <= 4:
                output += "A "
                total += 11
                player.append("A")
            elif card <= 8:
                output+="2 "
                total+=2
                player.append("2")
            elif card <= 12:
                output+="3 "
                total+=3
                player.append("3")
            elif card <= 16:
                output+="4 "
                total+=4
                player.append("4")
            elif card <= 20:
                output+="5 "
                total+=5
                player.append("5")
            elif card <= 24:
                output+="6 "
                total+=6
                player.append("6")
            elif card <= 28:
                output+="7 "
                total+=7
                player.append("7")
            elif card <= 32:
                output+="8 "
                total+=8
                player.append("8")
            elif card <= 36:
                output+="9 "
                total+=9
                player.append("9")
            elif card <= 40:
                output+="10 "
                total+=10
                player.append("10")
            elif card <= 44:
                output+="J "
                total+=10
                player.append("J")
            elif card <= 48:
                output+="Q "
                total+=10
                player.append("Q")
            elif card <= 52:
                output+= "K "
                total+=10
                player.append("K")
            if len(player) >= 2 and total <=21:
                print(f"{output} ({total}) ")

        if total > 21:

            if "A" in player: #Ask why ace always messes up
                if count < 1:
                    count +=1
                    total-=10
                    print(f"{output} ({total}) ")
                if player.count("A") > 1:
                    total -= 10
                    print(f"{output} ({total}) ")
            else:
                print(f"{output} ({total}) ")
                print("BUST!")
                return total

        if action_taken == "stand":
            return total

        if action_taken != "hit" or "stand":
            print("Enter a valid input ('hit' or 'stand') ")


play()

Upvotes: 1

Views: 130

Answers (2)

chuck
chuck

Reputation: 1447

if "A" in player will always be True once there's an ace in the deck, and so you never get to the else where you print "BUST!" and return, so the loop just continues. You can do something like incremeting count for every ace in the deck and then change the ace part to be:

    if total > 21:
        player_aces = player.count("A")  # How many aces the player has
        if player_aces != count: # Meaning there are aces that weren't checked
            for _ in range(player_aces - count):
                total -= 10  # Could also be simplified to: total -= 10 * (player_aces - count)
            count = player_aces
            print(f"{output} ({total}) ")
        else:
            print(f"{output} ({total}) ")
            print("BUST!")
            return total

Also, if action_taken != "hit" or "stand" doesn't check that action_taken is not "hit" and not "stand". An or treats both its inputs as bool values and returns whether at least one is True. The != operator has precedence over or, so the line is actually if (action_taken != "hit") or "stand". The left part of that does what it's supposed to do, but then the right part evaluates "stand" as a bool, and in python every non-empty string is evaluated as True. So the right expression is always True, and so is the or - and the program will always enter the if statement.

You probably want: if action_taken != "hit" and action_taken != "stand".

Upvotes: 2

CodeCupboard
CodeCupboard

Reputation: 1585

There were a coupe of issues that I have fixed. I have created a counter for the number of Aces, this allows us to count how many times we can reduced the total by - otherwise we just keep removing 10.

Also the indentation of the last else statement needed moving out.

import random


def play():
    output = "Your hand: "
    player = []
    total=0
    count = 0
    reducedA = 0
    while len(player) != 2:
        card = 1
        #card = random.randint(1,52)
        if card <= 4:
            output += "A "
            total += 11
            reducedA+=1
            player.append("A")
        elif card <= 8:
            output+="2 "
            total+=2
            player.append("2")
        elif card <= 12:
            output+="3 "
            total+=3
            player.append("3")
        elif card <= 16:
            output+="4 "
            total+=4
            player.append("4")
        elif card <= 20:
            output+="5 "
            total+=5
            player.append("5")
        elif card <= 24:
            output+="6 "
            total+=6
            player.append("6")
        elif card <= 28:
            output+="7 "
            total+=7
            player.append("7")
        elif card <= 32:
            output+="8 "
            total+=8
            player.append("8")
        elif card <= 36:
            output+="9 "
            total+=9
            player.append("9")
        elif card <= 40:
            output+="10 "
            total+=10
            player.append("10")
        elif card <= 44:
            output+="J "
            total+=10
            player.append("J")
        elif card <= 48:
            output+="Q "
            total+=10
            player.append("Q")
        elif card <= 52:
            output+= "K "
            total+=10
            player.append("K")
        if len(player) == 2:
            print(f"{output} ({total}) ")

    while len(player) >= 2:
        action_taken = input("Would you like to 'hit' or 'stand': ")
        if action_taken == "hit":
            card = random.randint(1,52)
            if card <= 4:
                output += "A "
                total += 11
                player.append("A")
                reducedA += 1
            elif card <= 8:
                output+="2 "
                total+=2
                player.append("2")
            elif card <= 12:
                output+="3 "
                total+=3
                player.append("3")
            elif card <= 16:
                output+="4 "
                total+=4
                player.append("4")
            elif card <= 20:
                output+="5 "
                total+=5
                player.append("5")
            elif card <= 24:
                output+="6 "
                total+=6
                player.append("6")
            elif card <= 28:
                output+="7 "
                total+=7
                player.append("7")
            elif card <= 32:
                output+="8 "
                total+=8
                player.append("8")
            elif card <= 36:
                output+="9 "
                total+=9
                player.append("9")
            elif card <= 40:
                output+="10 "
                total+=10
                player.append("10")
            elif card <= 44:
                output+="J "
                total+=10
                player.append("J")
            elif card <= 48:
                output+="Q "
                total+=10
                player.append("Q")
            elif card <= 52:
                output+= "K "
                total+=10
                player.append("K")
            if len(player) >= 2 and total <=21:
                print(f"{output} ({total}) ")

        if total > 21:

            if "A" in player: #Ask why ace always messes up
                if count < 1:
                    count +=1
                    total-=10
                    print(f"{output} ({total}) ")
                if player.count("A") > 1 and reducedA:
                    total -= 10
                    reducedA -= 1
                    print(f"{output} ({total}) ")
                else:
                    print(f"{output} ({total}) ")
                    print("BUST!")
                    return total
            else:
                print(f"{output} ({total}) ")
                print("BUST!")
                return total

        if action_taken == "stand":
            return total

        if action_taken != "hit" or action_taken != "stand":
            print("Enter a valid input ('hit' or 'stand') ")


play()

Upvotes: 2

Related Questions