When my code not exiting while loop in python? - python

It's a black jack game project. When user_score > 21 or 21 , it shold exit the while loop but it is not exiting while loop.I am new in coding. Plese tell me where is the problem.
I don't want to use break command. Because from which tutorial I am learning she has not taught me it yet.
You can get an idea of black jack game here.247blackjack
I tried these lines of code.
import random
def deal_card():
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
random_index = random.randint(0,(len(cards)-1))
random_card = cards[random_index]
return random_card
def want_another_card():
want_card = input("Want another card type 'y' for yes and type 'n' for no.")
return want_card
user_card = []
computer_card = []
for x in range(0,2):
user_card.append(deal_card())
computer_card.append(deal_card())
def calculate_score(list):
score = sum(list)
return score
user_score = calculate_score(user_card)
computer_score =calculate_score(computer_card)
#final score function
def final_score_calculation():
while calculate_score(computer_card)< 17:
computer_card.append(deal_card())
line_gap()
print(f"Your final hand: {user_card}, final score: {user_score}")
print(f"Computer's final hand: {computer_card}, final score: {computer_score}")
if user_score > computer_score and user_score < 21:
winner = "User"
print(f"{winner} wins")
elif computer_score > user_score and computer_score < 21:
winner = "computer"
print(f"{winner} wins")
elif computer_score > 21:
print("Computer busted. You win.")
elif user_score > 21:
print("User busted, Computer wins")
elif user_score == 21:
print("user wins")
elif computer_score == 21:
print("computer wins")
elif computer_score == user_score:
print("It's a draw")
should_continue = True
while should_continue == True:
print(f"Your cards: {user_card}, current score {calculate_score(user_card)}")
print(f"computer's first card {computer_card[0]}")
#checking if user or computer has a black jack
if user_score == 21 and len(user_card) == 2:
print("User has the blackJack. You win")
should_continue = False
elif computer_score ==21 and len(computer_card) == 2:
print("Computer has the black jack .You lose")
should_continue = False
#checking if they got busted or got 21
if user_score > 21: #checking user
if 11 in user_card:
usr_indx_pos=user_card.index(11)
user_card[usr_indx_pos] = 1
if user_score > 21:
print("you got busted.You lose.")
should_continue = False
elif user_score ==21:
print("you have 21 . you win")
should_continue = False
else:
print("you got busted.You lose.")
should_continue = False
elif computer_score > 21: #checking computer
if 11 in computer_card:
com_indx_pos = computer_card.index(11)
computer_card[com_indx_pos] = 1
if computer_score > 21:
print("computer busted. you win")
should_continue = False
else:
print("computer got busted. You win")
should_continue = False
elif user_score ==21:
print("you win. you got 21")
should_continue = False
elif computer_score ==21:
print("computer win. computer got 21")
should_continue = False
line_gap()
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False

Assuming your complaint is that it is prompting you if you want another card even after you bust (or win), the solution is to ensure you don't issue that prompt when the loop is supposed to be done anyway. Just change:
if want_another_card() == "y":
to:
if should_continue and want_another_card() == "y":
This will cause it to do the final_score_calculation() call in the else, which may be redundant; if it shouldn't report the results again when someone has already busted or got exactly 21, wrap the whole of:
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
in a check to see if it already knows it's done, making it:
if should_continue:
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
so it does no additional work when it already knows the game is over.

Related

Blackjack python game

I have to create a blackjack game in python in which the user inputs the number of decks that are being used and the amount of money the user wants to bet. The rules are: o The player places his bet (should be read from the keyboard).
o The dealer and player are dealt two cards (one card of the dealer should be hidden).
o If the player has 21 he wins his bet; else if the dealer has 21 then the dealer wins and the player loses his bet.
o The player can only select to draw a new card (hit) or pass. Repeat until the player passes or busts. If the player goes above 21 then he busts.
o Then the dealer draws cards (automatically) until he either busts or reaches 17 or higher.
o Values of cards: A= 1 or 11 (the highest that does not bust you) and J=Q=K=10
o Note: in blackjack there are more actions: insurance, double, split; those are not required to be implemented as they would make the code you have to produce much, much longer and harder
I will show you my code below when I tried to run it, it said that the name "total" is not defined on the function game, but earlier on I have already defined it. I don't know how can i fix it.
import random
N=int(input("Please enter number of decks of cards used: "))
deck= [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]*N
wins=0
losses=0
chip_pool = 100
bet = 1
def deal(deck):
hand = []
for i in range(2):
random.shuffle(deck)
card=deck.pop()
if card == 11:
card = "J"
if card == 12:
card = "Q"
if card == 13:
card = "K"
if card == 14:
card = "A"
hand.append(card)
return hand
def play_again():
again = input("Do you want to play again? (Y/N) : ").lower()
if again == "y":
dealer_hand = []
player_hand = []
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]*N
game()
else:
print("Thank you for playing.")
exit()
def total_hand():
total = 0
for card in hand:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
def hit(hand):
card = deck.pop()
if card == 11:
card = "J"
if card == 12:
card = "Q"
if card == 13:
card = "K"
if card == 14:
card = "A"
hand.append(card)
return hand
def print_results(dealer_hand, player_hand):
clear()
print("\n WELCOME TO BLACKJACK!\n")
print("The dealer has a " + str(dealer_hand) + "for a total of" + str(total(dealer_hand)))
print("You have a" + str(player_hand) + "for a total of" + str(total(player_hand)))
def blackjack(dealer_hand, player_hand):
global wins
global losses
if total(player_hand) == 21:
print_results(player_hand,dealer_hand)
print("Congratulations! You got a blackjack.\n")
wins = wins + 1
play_again()
elif total(dealer_hand) == 21:
print_results(dealer_hand,player_hand)
print("Sorry you lose. The dealer got a blackjack.\n")
chip_pool -= bet
loses = loses + 1
play_again()
def score(dealer_hand,player_hand):
if total(player_hand) == 21:
print_results(dealer_hand, player_hand)
print("Congratulations! You got a blackjack1\n")
elif total(dealer_hand) == 21:
print_results(dealer_hand, player_hand)
print("Sorry you lose. The dealer go a blackjack\n")
elif total(player_hand) > 21:
print_results(dealer_hand, player_hand)
print("Sorry, you busted. You lose.\n")
elif total(dealer_hand) > 21:
print_results(dealer_hand, player_hand)
print("Dealer busts. You win!\n")
chip_pool += bet
elif total(player_hand) < total(dealer_hand):
print_results(dealer_hand, player_hand)
print("Sorry, the score is not higher than the dealer. You lose.\n")
chip_pool -= bet
elif total(player_hand) > total(dealer_hand):
print_results(dealer_hand, player_hand)
print("Congratulations. Your score is higher than the dealer. You win.\n")
chip_pool += bet
elif total(player_hand) == total(dealer_hand):
print_results(playe_hand, dealer_hand)
print("There is a tie. In a tie dealer always wins!\n")
chip_pool -= bet
def make_bet():
global bet
bet = 0
print("What amount of chips would you like to bet? ")
while bet == 0:
bet_comp = input()
bet_comp = int(bet_comp)
if bet_comp >= 1 and bet_comp <= chip_pool:
bet = bet_comp
else:
print("Invalid bet, you only have" + str(chip_pool) + "remaining")
def game():
choice = 0
print("Welcome to Blackjack!\n")
dealer_hand = deal(deck)
player_hand = deal(deck)
print("The dealer is showing a " +str(dealer_hand[0]))
make_bet()
print("You have a " + str(player_hand))
blackjack(dealer_hand, player_hand)
quit = False
while not quit:
choice = input("Do you want to [H]it, [S]tand, or [Q]uit: ").lower()
if choice == 'h':
hit(player_hand)
print(player_hand)
if total(player_hand) > 21:
print("You busted")
chip_pool -= bet
play_again()
elif choice == "s":
while total(dealer_hand) < 17:
hit(dealer_hand)
print(dealer_hand)
if total(dealer_hand) > 21:
print("Dealer busts. You win!")
chip_pool += bet
play_again()
score(dealer_hand, playe_hand)
play_again()
elif choice == "q" :
print("Thank you for playing. Hope you enjoyed!")
quit = True
exit()
if __name__ == "__main__":
game()
You have not defined the function total that you call. Try adding this to your code
def total(array):
total = 0
for card in array:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
However I see some more issues in your code that will need fixing later on! Stand or Quit do nothing currently, and on busting there is an exception thrown since chip_pool never had a value assigned to it
EDIT 1:
You defined a function
def total_hand():
total = 0
for card in hand:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
Similar to what I suggested. Maybe it was just a typo but you need to do the following
Rename the function from total_hand to total OR call total_hand
Change the definition from total_hand() to total_hand(hand)

Is there a bug in this

I am totally new to programming. This is my second program so far. I have two challenges in this code.
For most of the initial runs this works fine in pycharm but after few runs this gives an error message like below. The bloc of code which is causing this error seems to be executing in the beginning and then its giving this error. Please someone help me with this.
Error message:
Traceback (most recent call last):
File "D:\Python\Practice\100 Days of coding\Day 11\Black Jack.py", line 81, in <module>
play_game()
File "D:\Python\Practice\100 Days of coding\Day 11\Black Jack.py", line 70, in play_game
while comp_score < 17:
TypeError: '<' not supported between instances of 'NoneType' and 'int'
Challenge 2: I have overserved that the cards stored for computer alter occasionally. I am unable to figure out why. Please help.
import random
def play_game():
def deal_card():
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
card = random.choice(cards)
return card
def calculate_score(card_list):
if sum(card_list) == 21:
if len(card_list) == 2:
return 0
else:
if 11 in card_list and sum(card_list) > 21:
card_list.remove(11)
card_list.append(1)
return sum(card_list)
def game_result():
print(f"Computer cards are {comp_cards} and computer score is {comp_score}.")
print(f"Your cards are {user_cards} and score is {user_score}.")
if comp_score == user_score:
print("Your scores are equal. Match Draw.")
elif user_score == 0:
print("Yay Black Jack! You win!")
elif comp_score == 0:
print("Computer has Black Jack. You loose.")
elif user_score > 21:
print("You went over 21. You loose.")
elif comp_score > 21:
print("Computer score went over 21. You win!")
elif user_score > comp_score:
print("You won!")
else:
print(f"Computer score {comp_score} is greater than your score {user_score}.\n You loose.")
print("Welcome to BlackJack!")
comp_cards = []
user_cards = []
for _ in range(2):
comp_cards.append(deal_card())
user_cards.append(deal_card())
user_score = calculate_score(user_cards)
print(f"Computer cards {comp_cards}")
print(f"Your cards are {user_cards} and your score is: {user_score}")
pass_ = False
while pass_ == False:
deal_a_new_card = input("Type 'y' to get another card and 'n' to pass. : ")
if deal_a_new_card == "y":
user_cards.append(deal_card())
user_score = calculate_score(user_cards)
else:
pass_ = True
if user_score > 21:
pass_ = True
print(f"Your cards are {user_cards} and your score is: {user_score}")
comp_score = calculate_score(comp_cards)
while comp_score < 17:
comp_cards.append(deal_card())
comp_score = calculate_score(comp_cards)
game_result()
play_again = 'y'
while play_again == "y":
play_game()
play_again = input("\nWould you like to play again? Enter 'y' to play. : ")
This occurs because there are some circunstances where calculate_score() is not returning any value.
You are only returning a value when 'the sum isn't 21' or 'when it's equal to 21 AND there are 2 cards'. But you should also return value if you got a sum of 21 in more than 2 cards.
So you need to include in line 13th of your code:
if sum(card_list) == 21:
if len(card_list) == 2:
return 0
#From here on:
else:
return another_value

How can I optimize the loop and condition statements?

winner = False
def player():
global winner
while winner==False:
print("player 1: please choose rock/paper/scissor !")
choice1 = input()
print("player 2: please choose rock/paper/scissor !")
choice2 = input()
if choice1!=choice2:
if choice1=="rock" and choice2=="scissor" :
print("player 1 is the winner, Congrats!!")
elif choice1=="rock" and choice2=="paper" :
print("player 2 is the winner, Congrats!!")
elif choice2=="rock" and choice1=="scissor" :
print("player 2 is the winner, Congrats!!")
elif choice2=="rock" and choice1=="paper" :
print("player 1 is the winner, Congrats!!")
elif choice1=="scissor" and choice2=="paper" :
print("player 1 is the winner, Congrats!!")
elif choice1=="paper" and choice2=="scissor" :
print("player 2 is the winner, Congrats!!")
else:
print("its a draw")
print("do you want to start a new game?,yes or no")
answer = input()
if answer=="yes":
print("lets start another game!")
winner = False
elif answer=="no":
print("see you next time!")
winner = True
player()
as you can see there is too much inefficient if statements in my code ,how can i minimize them if possible
def player():
while True:
print("player 1: please choose rock/paper/scissor !")
choice1 = input()
print("player 2: please choose rock/paper/scissor !")
choice2 = input()
beats = dict(
rock='scissor',
scissor='paper',
paper='rock',
)
if choice1 != choice2:
if beats[choice1] == choice2:
winner = 1
else:
winner = 2
print("player %s is the winner, Congrats!!" % winner)
else:
print("its a draw")
print("do you want to start a new game?,yes or no")
answer = input()
if answer == "yes":
print("lets start another game!")
else:
print("see you next time!")
break
player()
You can do something like this:
db = {'rockscissor': 1,
'rockpaper': 2,
'scissorrock': 2,
'scissorpaper': 1,
'paperrock': 1,
'paperscissor': 2}
if choice1!=choice2:
print("player {} is the winner, Congrats!!".format(db[choice1+choice2]
else:
print("its a draw")
and you can even add draws to the db as well:
db = {'rockscissor': 1,
'rockpaper': 2,
'scissorrock': 2,
'scissorpaper': 1,
'paperrock': 1,
'paperscissor': 2,
'paperpaper':0,
'rockrock':0,
'scissorscissor':0
}
then handle the if.

Variable not registering change in value

I wanted to make a simple Rock, Paper, Scissor game in Python. It goes well with the game, but the final scores are always being showed as a 0.
I wanted to show a smaller section of the code but, I don't know where the problem lies, so I am sorry for the length of the code.
I am still a novice learner, so please pardon me if the question is too silly or the code is not well formatted.
#Rock-Paper-Scissor Game
import random
print("Please enter your name:")
userName = input()
print("Welcome " + userName)
print("The following are the rules of the game:")
print("Press 'R' for Rock")
print("Press 'P' for Paper")
print("Press 'S' for Scissor")
print("This will be a 10 point match")
userTally = 0
compTally = 0
def gameProcess(userTally, compTally): #The process of the game. It increments or decrements the value depending on the result
print("Your turn:")
userInput = input()
computerChoice = random.choice(["R","P","S"])
if userInput == "R": #User Inputs R for Rock
if computerChoice == "R":
print("The computer chose Rock")
print("It's a Tie")
elif computerChoice == "P":
print("The computer chose Paper")
print("Computer Won")
compTally = compTally + 1
elif computerChoice == "S":
print("The computer chose Scissor")
print("You Won")
userTally = userTally + 1
elif userInput == "P": #User Inputs P for Paper
if computerChoice == "R":
print("The computer chose Rock")
print("You Won")
userTally = userTally + 1
elif computerChoice == "P":
print("The computer chose Paper")
print("It's a Tie")
elif computerChoice == "S":
print("The computer chose Scissor")
print("Computer Won")
compTally = compTally + 1
elif userInput == "S": #User Inputs S for Scissor
if computerChoice == "R":
print("The computer chose Rock")
print("Computer Won")
compTally = compTally + 1
elif computerChoice == "P":
print("The computer chose Paper")
print("You Won")
userTally = userTally + 1
elif computerChoice == "S":
print("The computer chose Scissor")
print("It's a Tie")
return(userTally,compTally)
def tryCount(): #The number of tries....
tryNum = 1
while tryNum < 11:
gameProcess(0, 0)
tryNum = tryNum + 1
tryCount()
print("You scored " + str(userTally))
print("The computer scored " + str(compTally))
if userTally > compTally:
print("CONGRATULATIONS, YOU WON.")
elif userTally < compTally:
print("Sorry, better luck next time.")
close = input()
if close == "Random Input.":
exit()
else:
exit()
You pass 0, 0 to gameProcess, which you treat as the scores within the function, and then return them modified, but you do not actually use the return value in the only place you call gameProcess (in tryCount), so the global userTally, compTally variables remain unchanged.
This is how you should change tryCount:
def tryCount(): #The number of tries....
global userTally, compTally
tryNum = 1
while tryNum < 11:
userTally,compTally=gameProcess(userTally,compTally)
tryNum = tryNum + 1

The number of tries never increments by more than one in Python - help please?

Whenever it takes me several tries to beat the game, it always says the number_of_guesses is 1, which isn't true. What have I done wrong?
My code:
import random
print("Welcome to Rock, Paper, Scissors. \nYou will be going up against the computer, who will randomly",
"choose an object to duel you with!")
user_win = False
while not user_win:
user_guess = input("\nChoose either Rock, Paper or Scissors: ")
user_guess = user_guess.lower()
if user_guess != "rock" and user_guess != "paper" and user_guess != "scissors":
print("You didn't enter a valid guess. Try again, please.")
user_guess = input("\nChoose either Rock, Paper or Scissors: ")
user_guess = user_guess.lower()
computer_guess = random.randint(1,3)
if computer_guess == 1:
computer_guess = "rock"
elif computer_guess == 2:
computer_guess = "paper"
else:
computer_guess = "scissors"
print("Your guess:", user_guess.capitalize(), "\nComputer guess:", computer_guess.capitalize())
number_of_guesses = 1
if user_guess == computer_guess:
print("\nThe game is a tie. You guessed", user_guess, "and so did the computer.")
number_of_guesses += 1
user_win = False
elif (user_guess == "rock" and computer_guess == "scissors") or (user_guess == "paper" and computer_guess == "rock"):
print("\nCongratulations! You have beaten the computer by playing", user_guess.capitalize(), "while the computer played", computer_guess.capitalize())
user_win = True
number_of_guesses += 1
else:
print("\nDamn! The computer won by playing", computer_guess.capitalize(), "while you played", user_guess.capitalize())
user_win = False
number_of_guesses += 1
if number_of_guesses == 1:
print("\nYou won, and it only took you %d try!" % number_of_guesses)
else:
print("\nYou won, and it only took you %d tries!" % number_of_guesses)
input("\nPress enter to exit the program.")
I think that's formatted correctly. It's not easy to put code in here. Thank you!
You are always setting numbers of guesses equal to 1 inside your loop:
print("Your guess:", user_guess.capitalize(), "\nComputer guess:", computer_guess.capitalize())
number_of_guesses = 1 # setting here
Set the number_of_guesses outside the while loop
First of all in the while loop you always initialize number_of_guesses = 1 on every run. That is why this will always be 1 in each run.
Take this initialization before the while.

Categories

Resources