Toluwalase Mebaanne
Toluwalase Mebaanne

Reputation: 1

Python -I am adding to list as long as sum of list is less than 17. the while loop works except when sum is between 12 & 16. I dont know why

I am writing a simple version of the Black Jack app. Everything works to the point where I check if computer/dealer has <=16. Here is an image of it working:

enter image description here

Once the user/player is done playing, A while loop checks if the computer SUM is <17, then deals continously until Computer sum is higher; before finally checking the winning conditions. I noticed that it all works except for when computer sum is between 12 & 16.It just haults.

enter image description here

I know there are several ways of doing this, I wrote this on my own and hope someone can look at it and tell me what I am doing wrong.

I am a newbie, so pardon any rookie or unclean code you find. I hope I provided enough detail. Thanks.

Here is my code:

import random

cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]

def black_jack():
    user = []
    computer = []

    def deal_card():
        """Deals a random card/number"""
        deal = random.choice(cards)
        return deal

    def ace_check():
        """This is checking list of cards for user and Computer
        --- Swaps 11 for 1 if sum is greater than 21"""
        if sum(user) > 21:
            for x in range(len(user)):
                if user[x] == 11:
                    user[x] = 1
        if sum(computer) > 21:
            for y in range(len(computer)):
                if computer[y] == 11:
                    computer[y] = 1

    def mask_hand():
        """Replaces the last item of the list with X...
        using a copy of the original list"""
        masked = computer.copy()
        # learnt about the .copy which creates a copy of list.
        masked[len(masked) - 1] = "X"
        return masked

    def winning_conditions():
        ace_check()
        if sum(computer) < sum(user) <= 21:
            winner = "User"
            print(f"user{user}={sum(user)}, computer{computer}={sum(computer)} - {winner} Wins!!!")
        if sum(user) < sum(computer) <= 21:
            winner = "Computer3"
            print(f"user{user}={sum(user)}, computer{computer}={sum(computer)} - {winner} Wins!!!")
        if sum(user) == sum(computer):
            print(f"user{user}={sum(user)}, computer{computer}={sum(computer)} - It's a DRAW!!!")
        if sum(computer) == 21 and sum(user) <= 21:
            winner = "Computer2"
            print(f"user{user}={sum(user)}, computer{computer}={sum(computer)} - {winner} Wins!!!")
        if sum(user) > 21:
            winner = "Computer1"
            print(f"user{user}={sum(user)}, computer{computer}={sum(computer)} - {winner} Wins!!!")
            return

    def comp_sum_check():
        while sum(computer) <= 16:
            computer.append(deal_card())
            return computer

    welcome = input(f"Welcome, are you ready to deal? y or n:\n")
    if welcome == "n":
        bye_message = "Bye!!!"
        return print(bye_message)
    elif welcome == "y":
        user.append(deal_card())
        user.append(deal_card())
        computer.append(deal_card())
        computer.append(deal_card())
        print(f"user{user}, computer{computer}")

        while sum(user) < 22:
            ask_deal = input(f"Would you like to deal? y or n:\n")
            if ask_deal == "n":
                comp_sum_check()
                winning_conditions()
                return
            elif ask_deal == "y":
                user.append(deal_card())
                ace_check()
                print(f"user{user}, computer{mask_hand()}")
        else:
            ace_check()
            winning_conditions()


black_jack()

Upvotes: 0

Views: 41

Answers (1)

trincot
trincot

Reputation: 351084

The issue is that you have a return statement that executes in the first iteration of this loop:

    def comp_sum_check():
        while sum(computer) <= 16:
            computer.append(deal_card())
            return computer

By consequence, the loop will never make a second iteration.

Move that return statement out of the loop's body:

    def comp_sum_check():
        while sum(computer) <= 16:
            computer.append(deal_card())
        return computer

Secondly, you're not replacing ace's values in this loop whenever the computer has one and exceeds 21. So it should be:

    def comp_sum_check():
        ace_check()
        while sum(computer) <= 16:
            computer.append(deal_card())
            ace_check()
        return computer

Finally,you don't print any result when none of the conditions in winning_conditions are true. Notably, if the computer busted, you don't print anything. That function suffers from code repetition (print statements, calculating the same sum over and over again) as well. You could solve the issue and reduce the code as follows:

    def winning_conditions():
        ace_check()
        computer_score = sum(computer)
        user_score = sum(user)
        print(f"user{user}={user_score}, computer{computer}={computer_score} - ", end="")
        if user_score > 21:
            print("Computer wins")
        elif computer_score > 21:
            print("User wins")
        elif computer_score == 21 or computer_score > user_score:
            print("Computer wins")
        elif user_score > computer_score:
            print("User wins")
        else:
            print("It's a draw")

This fixes the problem you mentioned. There are other issues, like for instance:

  • how you replace an ace's value to 1: this will not do the job right if the player has two aces. In that case you should not replace both of their values, but just one of them, and then continue until maybe there is again an excess value of 22 or more, and only then replace the other ace by 1.

  • The computer shouldn't deal more cards to itself when the user was busted. The rules are that if the user busted, the game immediately ends with a loss for that user.

  • You don't mask the computer's second card when starting the game. And although it doesn't matter much, it is actually the first card that should be masked according to the rules.

Upvotes: 0

Related Questions