Reputation: 167
I am currently experimenting with Python and programming a little text-adventure. In my game the player has certain properties like hp, attack damage and inventory slots for items. I want to be able to call these properties from everywhere in my code. For that I created a function that receives three values:
"edit": to specify if a variable should be edited
"info_id": to specify which variable should be accessed
"value": the new value for the variable
This is what it looks like in my code:
def player_info(edit, info_id, value):
if edit == 1:
##function wants to edit value
if info_id == 1:
player_hp = value
print ("Assigned hp to: ", player_hp)
##the "prints" are just to check if the asignments work -> they do
return player_hp
elif info_id == 2:
player_attack = value
print ("Assigned attack to: ", player_attack)
return player_attack
elif info_id == 3:
item_1 = value
return item_1
elif info_id == 4:
item_2 = value
return item_2
elif info_id == 5:
item_3 = value
elif edit == 0:
##function wants to retrieve value
if info_id == 1:
return player_hp
elif info_id == 2:
return player_attack
elif info_id == 3:
return item_1
elif info_id == 4:
return item_2
elif info_id == 5:
return item_3
There are actually 10 item slots (going up to info_id==13) but they are all the same anyway.
I define all variables at the beginning of my code:
player_info(1,1,20)
player_info(1,2,5)
n=3
while n<=13:
player_info(1,n,0)
n=n+1
##items are not fully implemented yet so I define the item slots as 0
The definition works, I can tell because of the control "print" I implemented in the code. Still when I call a variable, e.g. the health like this:
player_info(0,1,0)
I get an error:
local variable 'player_hp' referenced before assignment
Does the function not save the variable properly? Or what is the problem?
Is there a better way to save variables? Are global variables the way to go in this case?
Thanks for the help!
Upvotes: 1
Views: 240
Reputation:
You asked, "Does the function not save the variable properly?"
In general, Python functions do not save their state. The exception is functions that use the yield
statement. If you write a function like this
def save_data(data):
storage = data
and call it like this
save_data(10)
you will not be able to get the value of storage
later. In Python, if you need to save data and retrieve it later, you would normally use classes
.
Python classes
allow you do do things like this:
class PlayerData(object):
def __init__(self, hp=0, damage=0):
self.hp = hp
self.damage = damage
self.inventory = list()
self.max_inventory = 10
def add_item(self, item):
if len(self.inventory) < self.max_inventory:
self.inventory.append(item)
def hit(self, damage):
self.hp -= damage
if self.hp < 0:
self.hp = 0
def attack(self, other):
other.hit(self.damage)
if __name__ == '__main__':
player1 = PlayerData(20, 5)
player2 = PlayerData(20, 5)
player1.attack(player2)
print player2.hp
player1.add_item('sword')
player1.add_item('shield')
print player1.inventory
Output
15
['sword', 'shield']
This really only scratches the surface of how to use classes
. In a more complete implementation, you might have an Item
base class. Then you might create Sword
and Shield
classes that inherit from Item
.
Upvotes: 0
Reputation: 882
First of all, your error is caused because of retrieving a variable that is not assigned - that just doesn't work. When you edit player_hp
, it's not stored anywhere. you are returning it to the function that called it and not assigning it to anything. It just gets lost.
Second of all, you should really indent with 4 spaces (or tabs) - it's much more readable than 2 spaces. Not only for you, but for anyone trying to help too.
And lastly, the proper way to go about this would be to learn about classes. Global variables should never be used in python, only in special cases, or when you are learning, but just skip ahead to the class.
You should create something like
class Player:
def __init__(self):
self.hp = 20 # or another starting hp
self.attack = 3 # or another starting attack
self.inventory = []
Then you can just create an instance of Player class and pass it to the functions where it's relevant
player1 = Player()
print(player1.hp) # Prints out player's hp
player1.hp -= 5 # Remove 5 hp from the player. Tip: Use method to do this so that it can check if it reaches 0 or max etc.
player1.inventory.append("axe")
print(player1.inventory[0]) # Prints out axe, learn about lists, or use dictionary, or another class if you want this not to be indexed like a list
Upvotes: 1