I'm making a guess the number game. My code is almost complete but I need to make it so that the program asks the player if they want to play again and then restarts. Could someone help me with how I should go about that? I tried making a new function ex. def game_play_again and then call the game_play() function but it's not reseting the attempts which leads to it not looping correctly.
This is my code right now
import random
MIN = 1
MAX = 100
attempts = 5
win = False
number = random.randint(MIN,MAX)
last_hint = f"{'EVEN' if number%2 == 0 else 'ODD'}"
#print game instructions
def game_start():
print(f"Im thinking of a number between {MIN} and {MAX}. Can you guess it within
{attempts} attempts? ")
input("Press enter to start the game ")
#process user input
def game_play():
global number, attempts, last_hint, win
while attempts > 0:
print()
print(f"You have {attempts} {'attempts' if attempts > 1 else 'attempt'} left.")
if attempts == 1:
print(f"This is your last chance. So i'll give you one more hint. Its's an {last_hint} number.")
while True:
try:
guess = int(input("Try a lucky number: "))
if guess in range(MIN, MAX+1):
break
else:
print(f"Please enter numbers between {MIN} and {MAX} only!")
except ValueError:
print("Plese enter numbers only!")
if guess == number:
win = True
break
if attempts == 1:
break
if guess > number:
if guess-number > 5:
print("Your guess is too high. Try something lower.")
else:
print("Come on you are very close. Just a bit lower.")
else:
if number-guess > 5:
print("Your guess is too low. Try something higher.")
else:
print("Come on you are very close. Just a bit higher.")
attempts -= 1
#print game results
def game_finish(win):
if win:
print("Congratulations you guessed it!")
else:
print(f"The number I was thinking of is {number}. Sorry you lost. Better luck next time!")
game_start()
game_play()
game_finish(win)
You can simply reset your variables to initial values and then call game_play()
def game_finish(win):
if win:
print("Congratulations you guessed it!")
else:
print(f"The number I was thinking of is {number}. Sorry you lost. Better luck next time!")
want_play_again = int(input("Want play again? [1-Yes / 2-No]"))
if want_play_again == 1:
game_play_again()
else:
print("Bye")
/
def game_play_again():
attempts = 0
win = False
game_play()
Within a while(True) loop, write a menu driven statement asking the user if they want to repeat. If they do, initialise values and call game methods. If they do not, break the loop.
pseudocode:
while(True):
choice = input('play again? y/n)
if choice=='y':
attempts, win = 5, False
number = random.randint(MIN,MAX)
last_hint = f"{'EVEN' if number%2 == 0 else 'ODD'}"
game_start()
game_play()
game_finish()
elif choice=='n':
break
else:
print('invalid input')
The above code should be in main, with all methods within its scope.
Better yet, in place of all the initializations, add an init() method declaring them and call them when necessary.
The indentation in the code you have submitted is faulty, so I'm not sure if a related error is involved.
I am trying to create a simple code guessing game where the user can choose the minimum and maximum number the randomly generated code can be. The user has to try and guess the code to win. When I run my code, the get_range() function works and then it proceeds to the get_guess() function as it should. But when the user enters his/her input for their guess, the code loops back to the start of the get_range() function. Please can anyone help? Thanks in advance. Code:
import random
import string
print("Welcome to Code Crunchers!")
def get_range():
Min = str(input("Enter the minimum number that the code can be: "))
Max = str(input("Enter the maximum number that the code can be: "))
Check_Min = Min.isdigit()
Check_Max = Max.isdigit()
if Check_Min != True or Check_Max != True:
print("Input must only contain integers!")
get_range()
elif Min == Max:
print("Minimum and maximum number must not be equivalent!")
get_range()
elif Min > Max:
print("Maximum number must be greater than minimum number!")
get_range()
else:
Random_Number = random.randrange(int(Min), int(Max))
get_guess()
return Random_Number
def get_guess():
Guess = str(input("Enter your guess: "))
Check_Guess = Guess.isdigit()
if Check_Guess != True:
print("Input must only contain integers!")
get_guess()
else:
validate()
return Guess
def validate():
Random_Number = get_range()
Tries = locals()
Guess = get_guess()
Length = len(str(Random_Number))
Digits_Correct = 0
if Guess == Random_Number:
print("Well done! You guessed the number in", Tries, " tries!")
else:
Digits = ["?"] * Length
Tries += 1
for i in range(0, int(Length)):
if Guess[i] == Random_Number[i]:
Digits[i] = Guess[i]
Digits_Correct += 1
else:
continue
if int(Length) > Digits_Correct > 0:
print("Not quite! You got", Digits_Correct, " digits correct.")
print(Digits)
get_guess()
elif Digits_Correct == 0:
print("None of your digits match!")
get_guess()
def play_again():
Choice = input("Do you want to play again (y/n)?")
if Choice != "y" or Choice != "n" or Choice != "Y" or Choice != "N":
print("Please choose a valid option!")
play_again()
elif Choice == "y" or Choice == "Y":
get_range()
elif Choice == "n" or Choice == "N":
exit()
get_range()
Because you're re-calling get_range() in validate():
def validate():
Random_Number = get_range() # <-- Here
...
You might be able to solve this with:
def validate():
Random_Number = random.randrange(int(Min), int(Max))
...
But overall, that will depend on the direction of your code. Hope that helps!
Take a look at this code:
def get_range():
...
else:
...
get_guess()
return Random_Number
def get_guess():
...
else:
validate()
return Guess
def validate():
Random_Number = get_range()
Tries = locals()
Guess = get_guess()
...
Suppose you're in get_guess and get to the else close, so you call validate. Here's what happens:
get_guess calls validate
validate immediately calls get_range
get_range calls get_guess
now we're back in get_guess, see (1)
So your code enters infinite indirect recursion.
Notice how it'll never get past Random_Number = get_range() in validate, and you're calling get_guess in both get_range and validate.
So, before returning the random number to Random_Number = get_range(), get_range will try to get_guess and immediately discard its return value (that's what get_guess() does). Suppose that get_range eventually returns. Now you'll call Guess = get_guess() again, thus asking the user to guess twice. I think there's a logic flaw here.
I am trying to make a guess game. I've used while, if, elif, and else statements but I'm stuck on how to use for and while loops as well as randomizing single hints and single answers from a nested lists.
black_box = ["guam","lakers","flash","buddha","drake","fortnite","annabelle","xmen","mars","dad"]
nested_list = [["island","yigo","cocos","kelaguen"],["kobe","la","magic","lebron"],["scarlet","speedster","dc","ezra"], ["asiangod","meditation","monk","enlightenment"],["rapper","onedance","canadian","raptors"],["game","epic","notminecraft","dances"],["doll","conjuring","soultaker","creation"],["wolverine","mystique","magneto","apocalypse"],["red","fourth","planet","ares"], ["man","american","peter","lionking"]]
i = random.randint(0,9)
word = black_box[i]
hint = nested_list[i]
print("Guess the word with the following hint: ", hint, "you have 4 tries.")
numofguesses = 0
guess = input("What is the word? ")
while numofguesses < 4:
numofguesses = numofguesses + 1
if guess == word:
print("You win!")
option = input("Do you want to try again or quit? ")
if option == "try again":
print("")
elif option == "quit":
break
if guess != word:
print("Try again!")
guess = input("What is the word? ")
if guess != word:
print("Try again!")
guess = input("What is the word? ")
I expected to get a line of code that prints "Try again!" but it skipped and started to print "What is the word? " print("Guess the word with the following hint: ", hint, "you have 4 tries.") Originally, I used hint[i] which printed out only one hint in the nested list but then I tried to run the program again but I got an error saying, "list index is out of range.
Your condition checks and loops where not correct. Try the below code, it should work fine.
black_box = ["guam","lakers","flash","buddha","drake","fortnite","annabelle","xmen","mars","dad"]
nested_list = [["island","yigo","cocos","kelaguen"],["kobe","la","magic","lebron"],["scarlet","speedster","dc","ezra"], ["asiangod","meditation","monk","enlightenment"],["rapper","onedance","canadian","raptors"],["game","epic","notminecraft","dances"],["doll","conjuring","soultaker","creation"],["wolverine","mystique","magneto","apocalypse"],["red","fourth","planet","ares"], ["man","american","peter","lionking"]]
while True:
i = random.randint(0, 9)
word = black_box[i]
numofguesses = 0
while numofguesses < 4:
hint = nested_list[i][numofguesses]
print("Guess the word with the following hint: ", hint, ". You have ", 4 - numofguesses, " tries!")
guess = input("What is the word? ")
numofguesses = numofguesses + 1
if guess == word:
print("You win!")
break
if guess != word:
print("Try again!")
option = input("Do you want to try again or quit? ")
if option == "try again":
print("")
else:
break
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.