Reputation: 91
from random import random
# This function handles the number guessing and number formatting
def run_game():
# rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounds to nearest integer
rand = round(random() * 100, 0)
print("Guess the number [0 - 100]")
guesses = 0
while True:
# 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)
if n > int(rand):
print("Number is less than " + str(n))
guesses = guesses + 1
elif n < int(rand):
print("Number is greater than " + str(n))
guesses = guesses + 1
else:
guesses = guesses + 1
print("It took you " + str(guesses) + " guesses to guess the right number!")
reply = play_again()
if reply is False:
break
else:
run_game()
else:
print("Please enter a number")
def play_again():
while True:
reply = input("Play again? (y/n)\n")
if reply.lower() == "y":
return True
elif reply.lower() == "n":
return False
else:
print("Enter 'y' or 'n'")
if __name__ == "__main__":
run_game()
So when I run this program, it runs fine. Once guessing the number, I can type y or n to play again. If I have only played once, it works fine. But if I select y, and play again, entering n after playing the second game does nothing
Upvotes: 2
Views: 51
Reputation: 25
There's no point in returning True or False according to the user input, you can work from there directly.
import sys
from random import random
# This function handles the number guessing and number formatting
def run_game():
# rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounds to nearest integer
rand = round(random() * 100, 0)
print("Guess the number [0 - 100]")
guesses = 0
while True:
# 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)
if n > int(rand):
print("Number is less than " + str(n))
guesses = guesses + 1
elif n < int(rand):
print("Number is greater than " + str(n))
guesses = guesses + 1
else:
guesses = guesses + 1
print("It took you " + str(guesses) + " guesses to guess the right number!")
play_again()
else:
print("Please enter a number")
def play_again():
while True:
reply = input("Play again? (y/n)\n")
if reply.lower() == "y":
run_game()
elif reply.lower() == "n":
sys.exit(0)
else:
print("Enter 'y' or 'n'")
if __name__ == "__main__":
run_game()
This way the code is somewhat cleaner and fixes your problem. There's no point in passing "flags" around when you can do things directly.
Since your game is from 0 to 100 you should also verify if the user doesn't put a number that's bigger than 100, since lower than 0 doesn't pass the isdigit
check.
Upvotes: 0
Reputation: 104702
Your main issue is that you're using recursion to start a new game, but after the recursive call returns (assuming it does), you just keep on going in the original game.
There are a few ways you could fix that. The simplest would be to change the code that handles checking the user's choice to play again so that it always break
s:
if reply:
run_game()
break
A better approach would be to get rid of the recursion. There are a few ways you could do that. One simple idea is to simply reset the appropriate variables and keep right on going with your game loop when the user wants to play again:
reply = play_again()
if reply:
rand = round(random() * 100, 0)
print("Guess the number [0 - 100]")
guesses = 0
else:
break
Another way to avoid recursion would be to add another loop. Here's one way you could do it with a separate function:
def run_game():
rand = round(random() * 100, 0)
print("Guess the number [0 - 100]")
guesses = 0
while True:
answer = input()
if answer.isdigit():
n = int(answer)
if n > int(rand):
print("Number is less than " + str(n))
guesses = guesses + 1
elif n < int(rand):
print("Number is greater than " + str(n))
guesses = guesses + 1
else:
guesses = guesses + 1
print("It took you " + str(guesses) + " guesses to guess the right number!")
break # unconditionally break here!
def run_many_games():
again = True
while again:
run_game()
again = play_again()
One thing you may note that I've changed in all of the code above is how I test if the return value from play_again
is True
or False
. There's no need for an extra comparison step when you have a bool
value already. Just do if reply
(or if not reply
if you're testing for False
). You can also do this in a while
loop condition, as I do with again
in my last code block.
Upvotes: 2
Reputation: 126
The reason this is happening is because run_game
ends up calling itself recursively. Instead of restarting the game when the user chooses to play again it effectively creates a new instance of the game. Then when the user chooses to stop playing it returns back to the old session instead of exiting the program.
You can even prove this to yourself by remembering the solution before choosing to play again, and then choosing not to play again after the second session. You'll then be playing the previous session again and entering the solution you remembered or wrote down.
Now you can solve this problem by using sys.exit()
instead of break
to force the program to close, but that doesn't seem like good practice. If somebody chooses to play again too many times they can cause the program to run out of stack space and crash. Instead it's probably better to move that check out of run_game
like this
if __name__ == "__main__":
while True:
run_game()
if not play_again():
break
And modify the else block in run_game
to this
else:
guesses = guesses + 1
print("It took you " + str(guesses) + " guesses to guess the right number!")
break
Upvotes: 0
Reputation: 1
Heres a good way to solve this problem. In your code you never actually exit the while loop because run game never exits, and there is no system variable returned to break it. Using sys.exit(0) also works, but its a bad habit to get into for these kinds of programs.
from random import random
# This function handles the number guessing and number formatting
def run_game():
# rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounds to nearest integer
rand = round(random() * 100, 0)
print("Guess the number [0 - 100]")
guesses = 0
while True:
answer = input()
if type(answer) == int:
n = int(answer)
if n > int(rand):
print("Number is less than " + str(n))
guesses = guesses + 1
elif n < int(rand):
print("Number is greater than " + str(n))
guesses = guesses + 1
else:
guesses = guesses + 1
print("It took you " + str(guesses) + " guesses to guess the right number!")
break
reply = play_again()
if reply:
run_game()
else:
print 'Thank you for playing'
def play_again():
while True:
reply = raw_input("Play again? (y/n)\n")
if reply.lower() == "y":
return True
elif reply.lower() == "n":
return False
else:
print("Enter 'y' or 'n'")
if __name__ == "__main__":
run_game()
Upvotes: 0