I am trying to create a weapon that provides random damage. I am doing so using an item database in the form
itemsList = {
1: {"name": "Padded Armor", "armor": 1, "value": 5, "class": "Light"},
2: {"name": "Leather Armor", "armor": 2, "value": 10, "class": "Light"},
....
19: {"name": "Dagger", "damage" : int(random.randrange(1, 4)), "value": 2, "Type": "Dagger"},
20: {"name": "Dagger + 1", "damage" : int(random.randrange(1, 4) + 1), "value": 200, "Type": "Dagger"},
21: {"name": "Dagger + 2", "damage" : int(random.randrange(1, 4) + 2), "value": 750, "Type": "Dagger"},
22: {"name": "Dagger + 3", "damage" : int(random.randrange(1, 4) + 3), "value": 2000, "Type": "Dagger"}
}
Every time I attempt to call "damage"
it just returns the same result. I understand that this is because the random number is generated one and then saved to that dictionary key.
How would I go about generating a random number every time damage is called?
I would go to the trouble of making the things in itemsList
instances of a class. Although you might think that's overkill, doing it will give you a lot of programming flexibility later. It'll also make a lot of the code easier to write (and read) because you'll be able to refer to things using dot notation instead of via indexing which means you'll not only be able write to now use itemsList[19].damage
instead of itemsList[19]["damage"]
. You'll also use the same syntax for all other attributes such as itemsList[1].name
and itemsList[2].value
, as well as be able to write conditional code like this:
if hasattr(itemsList[2], 'Class'):
# do something based on itemsList[2].Class
Here's what I mean:
import random
class Gear(object):
def __init__(self, **kwargs):
kwargs['_damage'] = kwargs.pop('damage', False)
self.__dict__.update(kwargs)
@property
def damage(self):
return int(random.randrange(*self._damage)) if self._damage else 0
itemsList = {
1: Gear(name="Padded Armor", armor=1, value=5, Class="Light"),
2: Gear(name="Leather Armor", armor=2, value=10, Class="Light"),
# ...
19: Gear(name="Dagger", damage=(1, 4), value=2, Type="Dagger"),
20: Gear(name="Dagger + 1", damage=(1, 5), value=200, Type="Dagger"),
21: Gear(name="Dagger + 2", damage=(1, 9), value=750, Type="Dagger"),
22: Gear(name="Dagger + 3", damage=(2, 6), value=2000, Type="Dagger"),
}
To answer your follow-on questions in one comment below:
kwargs
is a dictionary of all the keyword arguments passed to the __init__()
constructor method. (__dict__
is the name of a dictionary where each instance stores its attributes.) See this section in the documentation.
damage
is defined by the class using a @property
decorator which is a simple way to actualy make it a "data descriptor". This sets things up so that whenever you reference a class instance's damage
attribute, it will call a function to retrieve/determine its current "value". See the Descriptor HowTo Guide for more information on Python descriptors.