I just started to learn Python. I am going through a book and making a text based game.
So I have a room. I want to make the player die if he/she comes into the room 3 times but couldn't figure out how to do.
def spawn():
count = 0
count += 1
print(count)
print("You dropped down nearly to the magma.")
print("There are four doors around you.")
print("Which one do you take?")
ch = input("Top, bottom, left or right? > ")
if count = 4:
dead("You wandered around too much and died.")
else:
print()
I tried to track the number with printing but I can't make it increase. What am I doing wrong?
EDIT: When I put count outside the function it gives:
Traceback (most recent call last):
File "ex.py", line 147, in <module>
spawn()
File "ex.py", line 14, in spawn
count += 1
UnboundLocalError: local variable 'count' referenced before assignment
Well in the function you each time set a local variable to 0, so that means that after the function is done, that variable no longer exists.
The trick is to use a variable that remains "active" after the function exists. For example a variable outside the function, or you can add an attribute to the function that you increment. The advantage of the latter is that it is more clear that this is something related to the function, like:
def spawn():
spawn.count += 1
print(spawn.count)
print("You dropped down nearly to the magma.")
print("There are four doors around you.")
print("Which one do you take?")
ch = input("Top, bottom, left or right? > ")
if spawn.count == 4:
dead("You wandered around too much and died.")
else:
print()
spawn.count = 0
Note that you also forgot to use double equal signs (==) for the if statement (equality check versus assignment).
Or you can do it like this:
def spawn():
if not hasattr(spawn, 'count'):
spawn.count = 0
spawn.count += 1
print(spawn.count)
print("You dropped down nearly to the magma.")
print("There are four doors around you.")
print("Which one do you take?")
ch = input("Top, bottom, left or right? > ")
if spawn.count == 4:
dead("You wandered around too much and died.")
else:
print()
Related
import random
import itertools as it
def guessthenumber():
play = input("do you want to play ?\nanswer yes or no :")
while play != "yes" :
if play == "no" :
quit()
else:
guessthenumber()
break
guessthenumber()
answer = random.randint(1, 5)
def random_func():
gusse = int(input("choose a number between 0 and 10"))
count = 3
while gusse != answer and count != 0 :
count -= 1
print(count)
print("wrong")
random_func()
break
random_func()
print("won")
Why does the guess count stop at 2 even with for loop?
The primary issue is as pointed out by #quamrana. When you call random_func you are adding a new stack frame that has a new count variable initialized to 3, so it immediately decrements, but then you add another call to random_func. You never return and pop this call off the stack, so there is no way to continue.
I don't see why ask if the caller wants to play. If it is the only thing the program does, running it is a pretty good indication. Also, is "gusse" a thing or just a misspelling of "guess".
You should avoid using quit() unless you are in an interpreter. You can use sys.exit, but in simple scenarios like this, returning and finishing the program is more simple.
Consider the following implementation with some slight improvements.
import random
def start(answer, tries):
while tries: # Continue while tries remain.
guess = int(input("choose a number between 0 and 10: "))
if guess == answer:
print("won")
return # Just return from the function.
tries -= 1 # Otherwise, decrement and continue.
print(f"wrong; tries remaining: {tries}")
if __name__ == "__main__":
answer = random.randint(1, 5)
start(answer, 3) # Begin the guessing part of the game.
Hello fellow programmers! I am a beginner to python and a couple months ago, I decided to start my own little project to help my understanding of the whole development process in Python. I briefly know all the basic syntax but I was wondering how I could make something inside a function call the end of the while loop.
I am creating a simple terminal number guessing game, and it works by the player having several tries of guessing a number between 1 and 10 (I currently made it to be just 1 to test some things in the code).
If a player gets the number correct, the level should end and the player will then progress to the next level of the game. I tried to make a variable and make a true false statement but I can't manipulate variables in function inside of a while loop.
I am wondering how I can make it so that the game just ends when the player gets the correct number, I will include my code down here so you guys will have more context:
import random
import numpy
import time
def get_name(time):
name = input("Before we start, what is your name? ")
time.sleep(2)
print("You said your name was: " + name)
# The Variable 'tries' is the indication of how many tries you have left
tries = 1
while tries < 6:
def try_again(get_number, random, time):
# This is to ask the player to try again
answer = (input(" Do you want to try again?"))
time.sleep(2)
if answer == "yes":
print("Alright!, well I am going to guess that you want to play again")
time.sleep(1)
print("You have used up: " + str(tries) + " Of your tries. Remember, when you use 5 tries without getting the correct number, the game ends")
else:
print("Thank you for playing the game, I hope you have better luck next time")
def find_rand_num(get_number, random, time):
num_list = [1,1]
number = random.choice(num_list)
# Asks the player for the number
ques = (input("guess your number, since this is the first level you need to choose a number between 1 and 10 "))
print(ques)
if ques == str(number):
time.sleep(2)
print("Congratulations! You got the number correct!")
try_again(get_number, random, time)
elif input != number:
time.sleep(2)
print("Oops, you got the number wrong")
try_again(get_number, random, time)
def get_number(random, try_again, find_rand_num, time):
# This chooses the number that the player will have to guess
time.sleep(3)
print("The computer is choosing a random number between 1 and 10... beep beep boop")
time.sleep(2)
find_rand_num(get_number, random, time)
if tries < 2:
get_name(time)
tries += 1
get_number(random, try_again, find_rand_num, time)
else:
tries += 1
get_number(random, try_again, find_rand_num, time)
if tries > 5:
break
I apologize for some of the formatting in the code, I tried my best to look as accurate as it is in my IDE. My dad would usually help me with those types of questions but it appears I know more python than my dad at this point since he works with front end web development. So, back to my original question, how do I make so that if this statement:
if ques == str(number):
time.sleep(2)
print("Congratulations! You got the number correct!")
try_again(get_number, random, time)
is true, the while loop ends? Also, how does my code look? I put some time into making it look neat and I am interested from an expert's point of view. I once read that in programming, less is more, so I am trying to accomplish more with less with my code.
Thank you for taking the time to read this, and I would be very grateful if some of you have any solutions to my problem. Have a great day!
There were too many bugs in your code. First of all, you never used the parameters you passed in your functions, so I don't see a reason for them to stay there. Then you need to return something out of your functions to use them for breaking conditions (for example True/False). Lastly, I guess calling functions separately is much more convenient in your case since you need to do some checking before proceeding (Not inside each other). So, this is the code I ended up with:
import random
import time
def get_name():
name = input("Before we start, what is your name? ")
time.sleep(2)
print("You said your name was: " + name)
def try_again():
answer = (input("Do you want to try again? "))
time.sleep(2)
# Added return True/False to check whether user wants to play again or not
if answer == "yes":
print("Alright!, well I am going to guess that you want to play again")
time.sleep(1)
print("You have used up: " + str(tries) + " Of your tries. Remember, when you use 5 tries without getting the correct number, the game ends")
return True
else:
print("Thank you for playing the game, I hope you have better luck next time")
return False
# Joined get_number and find_random_number since get_number was doing nothing than calling find_rand_num
def find_rand_num():
time.sleep(3)
print("The computer is choosing a random number between 1 and 10... beep beep boop")
time.sleep(2)
num_list = [1,1]
number = random.choice(num_list)
ques = (input("guess your number, since this is the first level you need to choose a number between 1 and 10 "))
print(ques)
if ques == str(number):
time.sleep(2)
print("Congratulations! You got the number correct!")
# Added return to check if correct answer is found or not
return "Found"
elif input != number:
time.sleep(2)
print("Oops, you got the number wrong")
tries = 1
while tries < 6:
if tries < 2:
get_name()
res = find_rand_num()
if res == "Found":
break
checker = try_again()
if checker is False:
break
# Removed redundant if/break since while will do it itself
tries += 1
I am trying to create a game where i think of a number in my head. And then the computer guesses the number through me telling it if its guess is too low or high.
This is what I've come up with but i am pretty lost tbh.
maxguess = 100
minguess = 1
count = 0
print("Think of a number between {} and {}".format(minguess,maxguess))
def midpoint(maxguess, minguess) :
z = ((maxguess + minguess)/2)
def guessing(x) :
print("Is you number greater (>) , equal (=) ,or less (<) than" ,z,)
print("please answer <,=, or >! >")
x = input()
if x == (">") :
minpoint = z
count += 1
continue
elif x == ("<") :
maxpoint = z
count += 1
continue
elif x == ("=") :
print ("I have guessed it!")
count += 1
break
print("I needed {} steps!".format(count))
Purposely not a complete solution, but some hints for you:
I'd recommend avoiding the global variables like count, maxguess, and minguess. Instead, make a function that holds all these variables.
Change your midpoint function to return z instead, then call it inside your guessing function.
Your continue and break functions would need to be inside a for or while loop. Since you aren't sure how many iterations you need to guess the number, I think a while loop would make sense here
Your functions are never run. On a style point, bring all your 'main' statements down to the bottom so they're together. After the prompt to think of a number, you need to call the guessing() function. When you call it, you should pass the minguess and maxguess values to it.
I can see what you're trying to do with the if...elif statements, but they need to be in a while True: block. So should the three statements preceding them so the script repeatedly asks for new advice from you.
Either bring the content of the midpoint() function into guessing() or make it return the value of z.
You also offer the user a choice of '>1' but don't handle it - and you don't need it as far as I can tell.
You never use minpoint or maxpoint - and you dont need them. Call the midpoint function instead and pass it the appropriate values, e.g., if '>', z = midpoint(z, maxguess).
Also, you're going to spend forever trying to get it to guess as you are using floats. Make sure everything is an integer.
Finally, you should add some code to manage input that isn't expected, i.e., not '<', '>' or '='.
Good luck!
minguess=1
maxguess=100
z=50
count=0
print("Think of a number between 1 and 100")
condition = True
while condition:
z=((maxguess + minguess)//2)
print("Is your number greater (>) , equal (=) ,or less (<) than" ,z,)
print("Please answer <,=, or >! >")
x = input()
if x == (">"):
minguess=z
count += 1
elif x == ("<") :
maxguess=z
count += 1
elif x == ("=") :
print ("I have guessed it!")
count += 1
condition=False
So I'm doing a project for an online class and when i got it scored it came back as not passed because my "play game" function was more than 18 lines long and I'm supposed to optimize it. The problem is they didn't make any suggestions as to what i should do and I keep looking at it and feel as if I need everything in it to make the fill in the blank quiz I'm building work. Any suggestions would be great as I am still very new to coding, and maybe what they are asking me to do is easy and I'm over complicating it in my head. This is the part of the code they want optimized...
def play():
'''
This is the main function which allows to play the game/quiz.
It calls the previous functions we have written.
'''
quiz = difficulty_level(user_level) #gives the difficulty
paragraph that the user asks for.
print quiz
print "\nYou will get maximum 3 guesses for each blank. Good luck.\n"
answers_list = relate_answer(user_level) #makes sure that the right
list is called up
blanks_index = 0
answers_index = 0
number_of_guesses = 3
while blanks_index < len(blanks): #This loop keeps going if all the
blanks are not replaced.
user_answer = raw_input("type in your answer for " + blanks[blanks_index] + ": ")
if check_answer(user_answer,answers_list,answers_index) == "Correct":
print "Awesome job! You gave the right answer!\n"
quiz = quiz. replace(blanks[blanks_index],user_answer)
blanks_index += 1
answers_index += 1
number_of_guesses = 3
print quiz
else:
number_of_guesses -= 1
if number_of_guesses == 0:
print "Game over! But try again!"
break
elif number_of_guesses < 0:
print "invalid"
break
else:
print "please try again."
print "You have " + str(number_of_guesses) + " guesses left."
print "Congratulations! You really know your stuff!."
play()
A quick summation of changes:
It looks like answers_index and blanks_index share the same state, no matter what, so we can generalize that to one variable idx. That cuts down on the number of variables you have to keep track of.
As others have suggested, initializing variables as a tuple like var1, var2 = 1, 2 decreases length and makes code more readable (to a point). If you have lots of variables to initialize, you can break the initialization into groups of related variables.
Setting a default value to user_level increases readability, and also gives an easy place to start debugging your function. This occurs in the def statement, so if you don't pass the argument, user_level will be 1, otherwise it will be whatever you give it in the function call. Example play(user_level=40) will overwrite that default value.
Putting the game loss condition at the start of the while loop increases visibility of the checks the code goes through before executing anything unnecessary. This should help you avoid the case where guess would be less than 0, because that code won't execute when guess==0 is True.
Setting a lose boolean with the check after exiting the while loop will also prevent the wrong print statement at the end from executing. That way, if the player loses, you will print the proper message.
Breaking the update of quiz into another function adds a more compact breakpoint into the code. In general, smaller functions that do less are preferable to large functions that do a lot. The smallest number of changes necessary is a good standard for what should be wrapped into a function, though this could be considered a stylistic convention more than a hard and fast rule.
The correct_answer method allows you to update quiz and guess in one line, and if something is wrong with the update itself, you don't have to run the entire script over and over. Instead you can take the quiz that might be causing the problem and plug it into that function until you find what's causing the problem.
I've made some minimal updates to the function you've provided which keep most of your conventions so far. Hopefully this is helpful, and happy coding!
def correct_answer(quiz, blank, answer):
"""
Function to update the quiz and return
both the quiz and reset guess to 3
"""
print("Awesome job! You gave the right answer!\n")
quiz = quiz.replace(blank, answer)
return quiz, 3
def play(user_level=1):
'''
This is the main function which allows to play the game/quiz.
It calls the previous functions we have written.
'''
idx, guess, lose = 0, 3, False
quiz = difficulty_level(user_level) #gives the difficulty paragraph that the user asks for.
print(quiz)
print("\nYou will get maximum 3 guesses for each blank. Good luck.\n")
answers_list = relate_answer(user_level) #makes sure that the right list is called up
while idx < len(blanks): #This loop keeps going if all the blanks are not replaced.
if guess <= 0:
lose = True
break
user_answer = raw_input("type in your answer for %s:" %str(blanks[idx]))
if check_answer(user_answer,answers_list,idx) == "Correct":
quiz, guess = correct_answer(quiz, blanks[idx], user_answer)
print(quiz)
else:
guess -= 1
print("please try again.\nYou have %s guesses left.\n"%str(guess))
idx += 1
if lose:
print("Game over, try again")
else:
print("Congratulations! You really know your stuff!.")
play(user_level = 3)
Despite importing the variable 'health' from a different module, the function below provides the error shown in the title. 'Health' is also globalised and I have removed both the globalisation and the importation of the variable and I still receive the same error.
Below is the function that is causing the issue.
def combat():
enemy_health = (random.choice(random_enemy_Health))
enemy_attack = (random.choice(random_enemy_Attack))
print("\nYou are fighting a" ,random.choice(enemies), "with an attack amount of" ,enemy_attack, "and a health amount of" ,enemy_health,".")
while health > 0 and enemy_health > 0:
if turn == 1:
while loop == False:
response=input()
try:
move = response("Do you want to attack or flee? Type '1' to attack and '2' to flee.")
move = int(move)
if move == 1:
enemy_health = enemy_health - attack
print("You attacked!")
loop = True
elif move == 2:
hub_travel()
print("You fled the battle, come back once you are stronger!")
loop = True
else:
print("Invalid number, try again")
continue
except:
print("Invalid number, try again")
continue
turn = 2
if turn == 2:
AImove = randint(1,2)
if AImove == 1:
print ("Enemy attacked!")
health = health - enemy_attack
turn = 1
continue
print ("game over!")
if enemy_health == 0:
print("The enemy has been defeated!")
gold += random.choice(gold_dropped)
The error occurs on this line in particular:
while health > 0 and enemy_health > 0:
If I were you, instead of relying on globals, I would use parameters. This advice may help you to track some errors.
Globals variables is a possibility in programs that have a few lines of code. But, when you application grows, it is a bit hard to track the current value of some variable, because it can be used in several functions or methods (probably, you need a mental mapping to find out the current value). So, this is one of the reasons why you must prefer to use local variables or parameters instead of globals.
This change would allow your function to work the way you want:
def combat(health):
...
Of course, you'd have to find the places where you call the function and pass in the value for health. I don't know if the code at that point has access to that information.
This is probably the simplest fix that could possibly address this issue. It is certainly not the best fix, but this is not a good place for an architecture tutorial.