EDIT: Thank you, the question has been answered!
The program works properly, asides from the fact that it does not loop to allow the user to play a new game. ie, after entering too many, too few, or the perfect amount of change, the program asks "Try again (y/n)?: " as it should. But I can't find out why it doesn't loop... And when it loops, it doesn't need to include the large paragraph about explaining the game. Just the line about "Enter coins that add up to "+str(number)+" cents, one per line." Any tips?
#Setup
import random
playagain = "y"
#Main Loop
if (playagain == "y"):
number = random.randint(1,99) #Generation of how many cents
total = 0 #Running sum of guessed coins.
print("The purpose of this exercise is to enter a number of coin values")
print("that add up to a displayed target value. \n")
print("Enter coins values as 1-penny, 5-nickel, 10-dime,and 25-quarter.")
print("Hit return after the last entered coin value.\n")
print("Enter coins that add up to "+str(number)+" cents, one per line.\n")
while (True):
if (total == 0):
word = "first"
else:
word = "next"
guess = str(input("Enter "+str(word)+" number: ")) #Records coin value
#Entry Validation
if (guess == ""): #When user is done guessing.
if (total < number):
print("Sorry - you only entered "+str(total)+" cents.\n")
break
elif (total > number):
print("Sorry - total amount exceeds "+str(number)+" cents.\n")
break
else:
print("Correct!")
break
elif (int(guess) == 1) or (int(guess) == 5) or (int(guess) == 10) or (int(guess) == 25):
total = total + int(guess)
else:
print("Invalid entry")
playagain = str(input("Try again (y/n)?: ")) #BRETT: I can't seem to get this to loop properly.
By using break, you're completely leaving the while loop and never checking the playagain condition. If you want to see if the user wants to play again put the 'playagain' check in another while loop.
#Setup
import random
playagain = "y"
#Main Loop
while (playagain == "y"):
number = random.randint(1,99) #Generation of how many cents
total = 0 #Running sum of guessed coins.
print("The purpose of this exercise is to enter a number of coin values")
print("that add up to a displayed target value. \n")
print("Enter coins values as 1-penny, 5-nickel, 10-dime,and 25-quarter.")
print("Hit return after the last entered coin value.\n")
print("Enter coins that add up to "+str(number)+" cents, one per line.\n")
while (True):
if (total == 0):
word = "first"
else:
word = "next"
guess = str(input("Enter "+str(word)+" number: ")) #Records coin value
#Entry Validation
if (guess == ""): #When user is done guessing.
if (total < number):
print("Sorry - you only entered "+str(total)+" cents.\n")
break
elif (total > number):
print("Sorry - total amount exceeds "+str(number)+" cents.\n")
break
else:
print("Correct!")
break
elif (int(guess) == 1) or (int(guess) == 5) or (int(guess) == 10) or (int(guess) == 25):
total = total + int(guess)
else:
print("Invalid entry")
playagain = str(input("Try again (y/n)?: ")) #BRETT: I can't seem to get this to loop properly.
You set playagain to y/n, but the code doesn't go back around to the beginning if playagain is equal to 'y'. Try making if playagain == "y" into while playagain == "y". That way, it goes through the first time and keeps going back to the beginning if playagain is still set to "y".
Also, indent your last line (playagain = str(....)) so it's part of the while playagain == "y" loop. If it's not, then the code will be stuck in an infinite loop because playagain isn't being changed inside the while loop.
Indent the last line as far as the while True line. And change the if (playagain == "y"): to a
while (playagain == "y"):
Your "Main loop" is not a loop, it is just an if statement. Also it is better to use raw_input because input will eval your input. Try something along the lines of this:
playagain = 'y'
#Main loop
while playagain == 'y':
print "do gamelogic here..."
playagain = raw_input("Try again (y/n)?: ")
Inside your gamelogic, you could use a boolean to check wether you need to print the game explanation:
show_explanation = True
while playagain == 'y':
if show_explanation:
print "how to play is only shown once..."
show_explanation = False
print "Always do this part of the code"
...
playagain = raw_input("Try again (y/n)?: ")
Related
def set_number():
import random
return random.randint(1,500)
#This function plays the game
def number_guessing_game(number):
guess_counter = 0
guess = int(input("Enter a number between 1 and 500."))
while guess != number:
guess_counter += 1
if guess > number:
print(f"You guessed too high. Try Again!")
guess = int(input("Enter a number between 1 and 500."))
elif guess < number:
print(f"You guessed too low. Try Again!")
guess = int(input("Enter a number between 1 and 500."))
if guess == number:
print(f"You guessed the number! Good Job.!")
again = str(input("would you like to play again? Enter 'y' for yes or 'n' to close the game."))
def main():
print(f"Welcome to the Number Guessing Game!\n" +
f"You will have unlimited guesses. The number is between 1 and 500.\n" +
f"Good Luck!")
number = set_number()
guess_count = number_guessing_game(number)
main()
I am working on a simple game project for my coding class. I am not good at coding at all. I came up with this part of the program, I just cannot figure out how to loop the entire number_guessing_game function until the user enters 'n' to stop it, I can't use a break because we did not learn it in the class and I will receive a 0 if I use a break.
I tried nesting a while loop inside of the function but I know I did it wrong.
Instead of using break use return.
def main():
print(f"Welcome to the Number Guessing Game!\n" +
f"You will have unlimited guesses. The number is between 1 and 500.\n" +
f"Good Luck!")
while True:
number = set_number()
number_guessing_game(number)
again = input("would you like to play again? Enter 'y' for yes or 'n' to close the game.")
if again == 'n':
return
main()
You will probably want to remove the last line of the number_guessing_game function if you use this approach
First, your code is assuming the return of input is an integer that can be converted with int(). If you were to give it 'n' your program will crash.
Instead you could use the string class method isdigit() to see if the input was an integer value and then make a logical decision about it. Also note you do not need to convert the return from input to a str() as it is already a str type. You can confirm this with a print(type(input("give me something")))
guess = input("Enter a number between 1 and 500. 'n' to quit"))
if guess.isdigit():
[your code to check the value]
elif ('n' == guess):
return
else:
print(f"You entered an invalid entry: {guess}. Please re-enter a valid value")
If you dont like the idea of using 'return' you could change your while loop to look something like:
while(('n' != guess) or (guess != number)):
If you want the function body looping continuously you could have some code like:
def number_guessing_game(number):
exit_game = False
guess_counter = 0
while(exit_game != True):
guess = input("Enter a number between 1 and 500.))
guess_counter += 1
if guess.isdigit():
if int(guess) > number:
print("You guessed too high. Try Again!")
elif int(guess) < number:
print("You guessed too low. Try Again!")
elif int(guess) == number:
print("You guessed the number! Good Job.!")
again = input("would you like to play again? Enter 'y' for yes or 'n' to close)
if ('n' == again):
exit_game = True
else:
print("Error, please enter a valid value")
How should I get the below loop to replay if the user types in an invalid response after being asked if they want to roll the dice again?
I can't get it to work without messing with the while loop. Here's what I have so far
# Ask the player if they want to play again
another_attempt = input("Roll dice again [y|n]?")
while another_attempt == 'y':
roll_guess = int(input("Please enter your guess for the roll: "))
if roll_guess == dicescore :
print("Well done! You guessed it!")
correct += 1
rounds +=1
if correct >= 4:
elif roll_guess % 2 == 0:
print("No sorry, it's", dicescore, "not", roll_guess)
incorrect += 1
rounds +=1
else:
print("No sorry, it's ", dicescore, " not ", roll_guess, \
". The score is always even.", sep='')
incorrect += 1
rounds +=1
another_attempt = input('Roll dice again [y|n]? ')
if another_attempt == 'n':
print("""Game Summary""")
else:
print("Please enter either 'y' or 'n'.")
I would suggest you do it with two while loops, and use functions to make the code logic more clear.
def play_round():
# Roll dice
# Compute score
# Display dice
# Get roll guess
def another_attempt():
while True:
answer = input("Roll dice again [y|n]?")
if answer == 'y':
return answer
elif answer == 'n':
return answer
else:
print("Please enter either 'y' or 'n'.")
def play_game():
while another_attempt() == 'y':
play_round()
# Print game summary
So I've created this number guessing game. And it works fine up until the play_again function is needed. I have looked around trying to figure out how I can restart the program. I have tested this in my PyCharm IDE and it just exits with exit code 0. What is the best way to actually restart the program so it generates a new number in my rand variable?
import os
from random import random
import sys
class Game:
"""
rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounding to the nearest integer
guessed is declared as false in order to keep the while loop running until the number is guessed
"""
rand = round(random() * 100, 0)
guessed = False
print("Guess the number [0 - 100]")
# This function handles the number guessing and number formatting
def run_game(self):
# Assigns the 'answer' variable by grabbing user input from console
answer = input()
# Checks if the input from the console is a number, and if not, asks the user to enter a valid number
if answer.isdigit():
n = int(answer)
# Checks the input given against the random number generated
while not self.guessed:
if n > int(self.rand):
print("Number is less than " + str(n))
self.run_game()
elif n < int(self.rand):
print("Number is greater than " + str(n))
self.run_game()
else:
print("You have guessed the correct number!")
self.guessed = True
self.play_again()
else:
print("Please enter a number")
self.run_game()
return
def play_again(self):
reply = input("Play again? (y/n)")
if reply.lower() == "y":
python = sys.executable
os.execl(python, python, *sys.argv)
elif reply.lower() == "n":
print("Thanks for playing!")
else:
self.play_again()
if __name__ == "__main__":
game = Game()
game.run_game()
Solution
There are several errors in your code. The most common being is that you are using recursion as a looping construct. Don't do this. It's a great way to introduce bugs, not to mention if your "loop" runs to many times, you'll hit the recursion limit. Just use a while loop:
def run_game(self):
while True:
answer = input()
if answer.isdigit():
n = int(answer)
if n > int(self.rand):
print("Number is less than " + str(n))
elif n < int(self.rand):
print("Number is greater than " + str(n))
else:
print("You have guessed the correct number!")
reply = self.play_again()
if reply is False:
break
else:
print("Please enter a number")
Note a modified player to return a boolean indicating whether the user wants to play again. As I said above, you made the same mistake in player. Don't use a recursion as a loop, use an explicit while loop:
def play_again(self):
while True:
reply = input("Play again? (y/n)")
if reply.lower() == "y":
return True
elif reply.lower() == "n":
return False
else:
print("Enter 'y' or 'n'")
Improvements
On an unrelated side note, I see no reason to use a class here. There's no global state you need to keep track of or any data you're trying to encapsulate. This can be implemented much cleaner using just functions:
def run_game():
rand = randint(1, 100)
while True:
answer = input()
if answer.isdigit():
n = int(answer)
if n > rand:
print("Number is less than " + str(n))
elif n < rand:
print("Number is greater than " + str(n))
else:
print("You have guessed the correct number!")
if not play_again():
break
else:
print("Please enter a number")
def play_again():
while True:
reply = input("Play again? (y/n)")
if reply.lower() == "y":
return True
elif reply.lower() == "n":
return False
else:
print("Enter 'y' or 'n'")
if __name__ == "__main__":
print("Guess the number [0 - 100]")
run_game()
Here are some other improvements I made:
I used ranint() instead of randomm(). Since you have a specific range, just use randint().
I removed the calls to int() as those are no longer needed.
That's a pretty bad way to restart the game, you should avoid running exec when possible.
One other way to do it would be to return False or True based on user input, and keep running the game while the function returns True:
import os
from random import random
import sys
class Game:
"""
rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounding to the nearest integer
guessed is declared as false in order to keep the while loop running until the number is guessed
"""
rand = round(random() * 100, 0)
guessed = False
print("Guess the number [0 - 100]")
# This function handles the number guessing and number formatting
def run_game(self):
# Assigns the 'answer' variable by grabbing user input from console
answer = input()
# Checks if the input from the console is a number, and if not, asks the user to enter a valid number
if answer.isdigit():
n = int(answer)
# Checks the input given against the random number generated
while not self.guessed:
if n > int(self.rand):
print("Number is less than " + str(n))
self.run_game()
elif n < int(self.rand):
print("Number is greater than " + str(n))
self.run_game()
else:
print("You have guessed the correct number!")
self.guessed = True
return self.play_again() # Here we run play_again and return its result
else:
print("Please enter a number")
self.run_game()
return
def play_again(self):
reply = input("Play again? (y/n)")
if reply.lower() == "y":
return False # Game isn't finished
elif reply.lower() == "n":
print("Thanks for playing!")
return False # Game is finished
else:
return self.play_again()
if __name__ == "__main__":
game = Game()
game_is_finished = False
while not game_is_finished:
game_is_finished = game.run_game()
Why wont this stop when 'n' is entered?
I've tried using break on the bottom else but I get errors doing that. That's a common problem I have with break. I have no idea why I'm thrown off with break.
import random
def game():
secret_num = random.randint(1, 10)
guesses = []
while len(guesses) < 5:
try:
guess = int(input("Guess a number between 1 and 10: "))
except ValueError:
print("{} isn't a number".format(guess))
else:
if guess == secret_num:
print("You got it! The number was {}.".format(secret_num))
break
elif guess < secret_num:
print("My number is higher than {}".format(guess))
else:
print("My number is lower than {}".format(guess))
guesses.append(guess)
else:
print("You didn't get it! My number was {}".format(secret_num))
play_again = input("Do you want to play again? Y/n ")
if play_again.lower() != 'Y':
game()
else:
print("Bye!")
game()
You convert play_again to a lower-case letter but compare it to an upper-case letter.
You could simply change it to:
if play_again.lower() != 'n': # 'y' was wrong, right?
game()
else:
print("Bye!")
return # works also without the explicit return but it makes the intention clearer.
I need to be able to prompt the user to enter an empty string so it can check if the answer is correct. but every time I do that I can error saying invalid literal for int()
so I need to change my user_input so it can accept int() and strings(). how do I make that possible ?
# program greeting
print("The purpose of this exercise is to enter a number of coin values")
print("that add up to a displayed target value.\n")
print("Enter coins values as 1-penny, 5-nickel, 10-dime,and 25-quarter.")
print("Hit return after the last entered coin value.")
print("--------------------")
#print("Enter coins that add up to 81 cents, one per line.")
import sgenrand
#prompt the user to start entering coin values that add up to 81
while True:
total = 0
final_coin= sgenrand.randint(1,99)
print ("Enter coins that add up to", final_coin, "cents, on per line")
user_input = int(input("Enter first coin: "))
if user_input != 1 and user_input!=5 and user_input!=10 and user_input!=25:
print("invalid input")
else:
total = total + user_input
while total <= final_coin:
user_input = int(input("Enter next coin:"))
if user_input != 1 and user_input!=5 and user_input!=10 and user_input!=25:
print("invalid input")
else:
total = total + user_input
if total > final_coin :
print("Sorry - total amount exceeds", (final_coin))
elif total < final_coin:
print("Sorry - you only entered",(total))
else:
print("correct")
goagain= input("Try again (y/n)?:")
if goagain == "y":
continue
elif goagain == "n":
print("Thanks for playing ... goodbye!" )
break
Store the value returned by input() in a variable.
Check that the string is not empty before calling int().
if it's zero, that's the empty string.
otherwise, try int()ing it.