I'am new to python, and i decided to make a simple quiz game.
The idea is:
Your base health is 100, every wrong answered question is -25 hp.
If hp equals 0 you lose.
And here lies the problem. I don't know how to pass the variable from function to a second function (in this case, every question in quiz is a different function)
The problem is that in every function, hp resets to its basic number (100).
Sorry if i poorly described my problem but im not very fluent in english.
Already tried to make a function that contains ,,hp = 100", making it global etc. Also tried various stuff with ,,return".
hp = 100
def test1():
test = input("yes no")
if test == "yes":
print("this is hp test")
print(hp - 25) # should be 100 - 25 = 75
test2()
if test == "no":
print("ok")
input("dead end")
def test2():
test2 = input("yes no")
if test2 == "yes":
print("this is second hp test")
print(hp - 25) # should be 75 - 25 = 50
if test2 == "no":
print("ok")
input("another dead end")
input("start")
test1()
I am not really sure what your trying to achieve here.
But i would suggest using a class that will allow you to have better control over your variables.
class Game:
def __init__(self):
self.hp = 100
def takeInput(self):
self.current = input()
self.computeScore()
def computeScore(self):
if self.input ==="Something":
self.hp -= 25
if self.checkValidScore():
self.takeInput()
else:
print "game over"
def checkValidScore(self):
return self.hp < 0
The statement print(hp - 25) simply prints the value of hp minus 25. It does not actually modify the value of hp. You probably want:
hp = hp - 25
print(hp)
Use global inside each function declartion
hp = 100
def test1():
global hp # do this in each of your functions
test = input("yes no")
if test == "yes":
print("this is hp test")
hp -= 25 # which is equivalent to hp = hp - 25
print(hp) # here just print the updated variable
test2()
Keep in mind that using global variables is not considered a good practice because it might make your code very hard to debug. You can read more about it here.
Not sure what you want to achieve. If it keeps that simple you could also go in the following direction...
def test1(hp):
test = input("yes no")
stop_msg = None
if test == "yes":
print("not ok")
hp -= 25
elif test == "no":
print("ok")
stop_msg = "dead end"
else:
raise Exception("Expected input to be 'yes' or 'no'.")
return hp, stop_msg
def test2(hp):
test = input("yes no")
stop_msg = None
if test == "yes":
print("'yes' sucks")
hp -= 25
elif test == "no":
print("ok")
stop_msg = "another dead end"
else:
raise Exception("Expected input to be 'yes' or 'no'.")
return hp, stop_msg
def run_game(hp=100):
print("start...")
tests = [test1, test2]
for test in tests:
hp, stop_msg = test(hp)
print("hp: {}".format(hp))
if stop_msg:
print(stop_msg)
return
if __name__ == "__main__":
run_game()
Remarks:
If you want to implement a more complex decision tree, you could use any simple tree representation.
If you have always the same structure within testX functions, introduce one function with parameters for questions, answer, etc.
Related
Im making a "game" for practice. Its a basic guess game, but i wanted to make the game only with functions. This is my problem (for ex.):
function 1:
variablaA
#some other code
function 2:
variableB
variableC = varibleA + variableB
#some other code
I have tried too goole about objects and classes but im not sure i understand what im doing right now.
import random
import sys
min = 1
max = 99
guessed_number = random.randint(min, max)
class functions:
def __init__(game, difficulty, lifes):
game.difficulty = difficulty
game.lifes = lifes
def GameDiff(hardness):
#Setting game difficulty
print "Select difficulty : \n 1; Easy \n 2; Medium \n 3; Hard \n"
difficulty = raw_input()
if difficulty == "1":
print "Its just the beginning"
lifes = 15
elif difficulty == "2":
lifes = 10
elif difficulty == "3":
lifes = 5
else:
print "This isn't an option try again"
GameDiff(hardness)
def core(basic):
#The core of the game
print "I guessed a number..."
player_number = int(raw_input("Whats the number I thinking of?"))
constant = 1
GameTime = 1
while GameTime == constant:
if player_number < guessed_number:
print "Your number is smaller than my guessed number"
print "Try to duplicate your number (But maybe Im wrong)"
player_number = int(raw_input("Make your tip again\n"))
elif player_number > guessed_number:
print "Your number is bigger than my guessed number"
print "Try to half your number (But maybe Im wrong)"
player_number = int(raw_input("Make your tip again\n"))
else:
GameTime = 0
print "You guessed it! Congratulations"
def main(self):
#The whole game only with functions
functions.GameDiff()
functions.core()
Function = functions()
Function.main()
if you are defining function with parameters, you need to pass data(parameters) into a function when you call it
example:
def my_function(name):
print("my name is " + name)
my_function("Kevin")
in your case you define:
def GameDiff(hardness):
def core(basic):
which are expecting parameters
and when you are calling those funcitions, you are doing that on wrong way:
def main(self):
#The whole game only with functions
functions.GameDiff()
functions.core()
Function = functions()
you need to pass parameters
example:
functions.GameDiff(5)
functions.core(1)
Function = functions(1,5)
NOTE: good practice will be to use self instead of game
def __init__(self, difficulty, lifes):
self.difficulty = difficulty
self.lifes = lifes
they are just two different kinds of class elements:
Elements outside the init method are static elements; they belong
to the class. They're shared by all instances.
Elements inside the init method are elements of the
object (self); they don't belong to the class.Variables created inside init (and all other method functions) and prefaced with self. belong to the object instance.
I have been using global variables for a little text game in python and have come across a lot of articles saying that global variables are a no no in python. I have been trying to understand how to get what I have below (just a health variable and being able to change it and print it) working using classes but I am confused how I can converted something like this in a class. Any help, example, point in the right direction would be great.
Here is an example of me using variables.
import sys
import time
health = 100
b = 1
def intro():
print("You will die after two moves")
def exittro():
time.sleep(1)
print("Thanks for playing!")
sys.exit()
def move():
global health
global b
health -= 50
if health <= 51 and b >0:
print("almost dead")
b = b - 1
def death():
if health == 0 or health <= 0:
print("...")
time.sleep(1)
print("You died\n")
time.sleep(2)
print("Dont worry, this game sucks anyway\n")
exittro()
intro()
a = 1
while a == 1:
input("Press Enter to move")
move()
death()
Thank you
Edit: this is the kind of thing I have been trying to do...
class Test:
def __init__(self):
number = 100
def __call__(self):
return number
def reduceNum(self):
number -=10
def printNum(self):
print(number)
a = 1
while a == 1:
input("Enter")
Test.self.reduceNum()
Test.self.printNum()
I would avoid classes for this, as classes are generally slower. You could make the function return the new value for the health variable.
I would also suggest making a main controller function to take the return value and apply it to other functions. This prevents global variables outside of a function's scope.
import time
def intro():
print("You will die after two moves")
def outro():
time.sleep(1)
print("Thanks for playing!")
# sys.exit() # You can avoid this now by just stopping the program normally
def move(health):
health -= 50
if health <= 51:
print("almost dead")
return health # Return the new health to be stored in a variable
def death(health):
if health <= 0:
print("...")
time.sleep(1)
print("You died\n")
time.sleep(2)
print("Dont worry, this game sucks anyway\n")
return True # Died
return False # Didn't die
def main():
health = 100 # You start with 100 health
intro()
while not death(health):
# While the death function doesn't return `True` (i.e., you didn't die) ...
input("Press enter to move")
health = move(health) # `health` is the new health value
outro()
If you want to use classes, you need to actually instantiate the class (Make a new object from it) by doing instance = Test(). You also need to store variables as attributes of self (so self.number = number) as any local variables are different from each other.
class Test:
def __init__(self):
self.number = 100
def __call__(self):
return self.number
def reduceNum(self):
self.number -= 10
def printNum(self):
print(self.number)
a = 1
game = Test()
while a == 1:
input("Enter")
game.reduceNum()
game.printNum()
# Or:
print(game())
# As you've changed `__call__` to return the number as well.
I'm having some issues with this code. There is a lot of other code to go with it but none that will interfere or have any affect on the issue I'm having. So basically, when I run the code and we get to the for loop at the bottom, it prints nothing because apparently the variable 'walls' = 0, even though I've already given it a valid input. If anyone could help it would be much appreciated.
global walls
global wallLengths
walls = 0
wall = 0
wallLengths = 0
def clientDetails():
#global walls
print("Welcome to the InHouse Solutions Room Painting Price Calculator")
print("STEP 1 - CLIENT DETAILS")
print("Please enter your full name")
userName = input(">>>")
print("Please enter your post code")
postCode = input(">>>")
print("Please enter you first address line here:")
addressLineOne = input(">>>")
print("Please enter your second address line here (OPTIONAL)")
addressLineTwo = input(">>>")
print("Thank you for your information")
print (userName)
print (addressLineOne + ", " + addressLineTwo + ", " + postCode)
print (" ")
def ValidationOne():
print ("Is this information correct? Pleast enter Yes or No")
clientDetailsCorrect = input(">>>")
if clientDetailsCorrect == "no" or clientDetailsCorrect == "No":
clientDetails()
elif clientDetailsCorrect == "Yes" or clientDetailsCorrect == "yes":
roomDimensions()
else:
("Invalid response, please try again")
ValidationOne()
ValidationOne()
def roomDimensions():
global walls
print ("STEP 2 - ROOM DIMENSIONS")
def ValidationTwo():
global walls
print ("How many walls does your room have?")
walls = int(input(">>>"))
if walls > 10 or walls < 3:
print("Invalid, please enter a number between 3 and 10")
ValidationTwo()
elif walls == " " or walls == "":
print("Invalid")
ValidationTwo()
def ValidationThree():
global walls
print ("How tall is the room in meters?")
roomHeight = float(input(">>>"))
if roomHeight < 2.4 or roomHeight > 6:
print ("Invalid, please enter a value between 2.4 and 6")
ValidationThree()
def IndividualWalls():
global wallLengths
global walls
for i in range(1,walls):
print("Please enter the width of wall" , i)
wallLengths[i] = float(input(">>>"))
ValidationTwo()
ValidationThree()
IndividualWalls()
clientDetails()
there is no need to use 'global' keyword when declaring a global at the top of the script:
>>> walls = 0
>>> def increase_walls():
... global walls
... walls += 1
... print walls
...
>>> increase_walls()
1
I can't comment to your question because I don't have over 50 reputation so I will ask here
Can you tell me what the function roomDimensions does?
I tried to run it and you have some deep recursion problem (you can't call recursion function without any if - it will run forever) BUT the first thing that I notice is that you don’t initialize the walls variable so it will not be global variable it will be non-local variable. and you don't call any inner function ( ValidationTwo, ValidationThree,IndividualWalls)
so you main problems are: (handle them in this order)
walls initialize
you didn't call any inner function
deep recursion
here is my example for the use of the three of above:
global_var = 12
def outer():
global global_var
print("*"*10)
print('hello im outer function')
print("*"*10)
def inner1():
global global_var
print('hello im inner1 function')
if global_var < 10:
return 'end for inner1'
print ('global_var is: ' + str(global_var))
global_var -= 1
return inner1()
def inner2():
global global_var
print('hello im inner2 function')
if global_var >= 10:
return 'end for inner1'
print ('global_var is: ' + str(global_var))
global_var += 1
return inner2()
if global_var >= 10:
return inner1()
else:
return inner2()
if __name__ == '__main__':
print outer()
Ok so im working on a basic dice game, But when it gets to the while loop it doesnt print the message inside, The message is just a placeholder.
dicenumber = None
numberchoice = None
ready = None
test = "Lol"
class playerClass():
points = 0
class enemyClass():
point = 0
def rolldice():
dicenumber = dicenumber.randint(1,9)
def start():
print("Hello welcome to the dice game.")
print("The goal of the game is to guess what number the dice will land on.")
print("The option are 1 to 6 and the game is won by getting 3 points.")
print()
print("Are you ready to play?")
print("1 - Yes")
print("2 - No")
ready = int(input())
start()
while ready == 1:
print("hello")
Use global inside your start function. Also, as you were trying to put while ready==1, it will be in infinite loop!
dicenumber = None
numberchoice = None
ready = None
test = "Lol"
class playerClass():
points = 0
class enemyClass():
point = 0
def rolldice():
dicenumber = dicenumber.randint(1,9)
def start():
global ready
print("Hello welcome to the dice game.")
print("The goal of the game is to guess what number the dice will land on.")
print("The option are 1 to 6 and the game is won by getting 3 points.")
print()
print("Are you ready to play?")
print("1 - Yes")
print("2 - No")
ready = int(input())
start()
while ready == 1:
print("hello")
When you access ready inside the start() method, you are accessing it as a local variable. Python assumes that all variables you use are local, not global. Put global ready in the start() method before you set the ready variable. This will tell python to access ready as a global variable.
There is a scoping issue. ready variable defined in a global scope is not updated inside the start() function.
Simple demo of what is happening:
>>> ready = None
>>> def start():
... ready = 1
...
>>> start()
>>> print ready
None
Better return ready variable from the start():
def start():
print("Hello welcome to the dice game.")
print("The goal of the game is to guess what number the dice will land on.")
print("The option are 1 to 6 and the game is won by getting 3 points.")
print()
print("Are you ready to play?")
print("1 - Yes")
print("2 - No")
return int(input())
ready = start()
You can also make it global as #S.M. Al Mamun suggested, but i would not recommend it. Global variables are needed for sharing data, state between functions. In this case there is no need for it - your start() function defines a value for the ready variable. It is a single one place where ready is defined - no need to make it global. start() is an entry point and it would be a good idea to return a "state" (ready variable) from it.
See also:
Short Description of the Scoping Rules?
ready is defined in the global scope, but you are setting it in the local scope of the start function. Also, your rolldice function returns a number from 1 to 9 instead of 1 to 6.
from random import randint
class Player:
def __init__(self, name):
self.name = name
self.points = 0
self.won = False
def add_point(self):
self.points += 1
self.won = True
print('''
Hello welcome to the dice game.
The goal of the game is to guess what number the dice will land on.
The options are 1 to 6 and the game is won by getting 3 points.
Are you ready to play?
0 - No
1 - Yes'''
ready = int(input())
if ready:
players = []
number_of_players = int(input('How many players? '))
for i in range(number_of_players):
name = input('What is the name of player {}?'.format(i+1))
players.append(Player(name))
winners = []
while ready:
random_number = randint(1, 6)
for player in players:
guess = int(input('What is your guess, {}?'.format(player.name)))
if guess == random_number:
player.add_point()
if player.won:
winners.append(player.name)
if winners:
print('Winners: {}'.format(', '.join(winners)))
break
You are accessing a variable(ready) which was defined originally as a global variable, then you are accessing it in your start function without mentioning in your code('start' function) that is a global variable and finally in your while loop you are again trying to access a variable which you assume it has a value assigned to it.
The other thing is you while loop. when you set ready==1, you need to some where break from your loop if you don't want it to be infinite loop.
A beginner's problem, here it goes:
I'm writing a program which keeps records of a game of darts. The user types in the players and their respective scores. It's possible to do a query about a player's scores and ask the program for the best overall score between all the players. I have the following functions:
add_score
return_players_score
return_best_score
exit_program
main
In main(), we begin by creating a new empty dictionary (say, players = {}). Then we ask the user to input a number that takes him/her to the function of choice (1: add_score etc.).
Now, once we're in add_score and have added a key:value pair (player:score), we need to go back to inputting the number taking to the function of choice. I implemented it simply by writing main() to the end of add_score.
That, however, takes us to the beginning, where there's players = {} and thus whatever data we input in add_score gets wiped out. This then affects other functions and the program remains useless as long as it forgets everything right away. How to solve this?
I'd paste the actual code but it's not in English and it's an assignment anyway...
Thanks.
Rather than calling main() from each of your other functions, you should just return (or run off the end of the function, which is equivalent to return None). Since you need the main function to run things repeatedly, you should use a loop.
def main():
players = {}
while True: # loop forever (until a break)
choice = input("what do you want to do (1-4)")
if choice == "1":
add_score(players)
elif choice == "2":
return_players_score(players)
#...
elif choice == "4":
break # break out of the loop to quit
else:
print("I didn't understand that.")
If you have a loop that does something like the following..
example:
while True:
players = {}
some code adding to players
This loop will always reset players to {}
However, if you do:
players = {}
while something:
some code adding to players
then players is not being reset at the start of each iteration through the loop
But your question is not clear
If you have something like this:
def add_score(dicccionary):
#do something with diccionary
main()
def main():
dicccionary = {}
while something:
option = input("option")
if option == 1:
addscore(dicccionary)
else:
#otherfunction
main()
your reset problem can be solve like:
dicccionary = {} #global variable
def add_score():
#do something with diccionary
main()
def main():
option = input("option")
if option == 1:
addscore()
else:
#otherfunction
main()
By the way, you shouldn't make it this way, try something as:
dicccionary = {} #global variable
def add_score():
#do something with diccionary
def main():
while somecondition:
option = input("option")
if option == 1:
addscore()
else:
#otherfunction
main()
If I was doing it for real then I would go for something like:
import sys
class ScoreKeeper(object):
def init(self):
self.scores = {}
def add_score(self, player, score):
self.scores[player] = score
def _print_player_score(self, player, score):
print 'player:', player, 'score:', score
def print_scores(self):
for player, score in self.scores.items():
self._print_player_score(player, score)
def best_score(self):
best, player = 0, "no player"
for player, score in self.scores.items():
if score > best:
best, player = score, player
self._print_player_score(player, best)
if __name__ == '__main__':
scorer = ScoreKeeper()
quit = lambda: sys.exit()
choices = quit, scorer.add_score, scorer.print_scores, scorer.best_score
def help():
print 'Enter choice:'
for index, c in enumerate(choices):
print '%d) %s' % (index, c.__name__)
def get_integer(prompt):
res = raw_input(prompt)
try:
return int(res)
except:
print 'an integer is required'
return get_integer(prompt)
def get_choice():
choice = get_integer('choice? ')
if not 0 <= choice < len(choices):
help()
return get_input()
return choice
help()
choice = get_choice()
while(choice):
args = []
if choices[choice] == scorer.add_score:
args.append(raw_input('player name? '))
args.append(get_integer('score? '))
choices[choice](*args)
choice = get_choice()
quit()