MalteK
MalteK

Reputation: 167

Programming a function that saves and returns values in python

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

Answers (2)

user3657941
user3657941

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

iScrE4m
iScrE4m

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

Related Questions