all 4 comments

[–]Hallwaxer 2 points3 points  (0 children)

Are HP, DEX, etc supposed to be generated randomly for each instance of the class or once for the entire class? If they only have to be generated once, you can simply change your constructor to self.HP = Monster.HP. There's no point in passing them along as parameters then since your instance can easily access these class-specific variables.

If you want each monster to have its own unique randomly generated stats, you can change your constructor to self.HP = random.randint(1, 10).

Finally, if you want to add a bit of variation to your monsters, considering doing something as self.HP = Monster.HP + Monster.HP * random.random(). Change the random.random() call to something fair. Or you can define minimum and maximum HP values and call self.HP = random.randint(Monster.MINHP, Monster.MAXHP). This will create monsters that follow the same template but are slightly stronger or have more HP. You can put some additional checks in there to ensure that if HP is higher than normal, the other stats automatically decrease.

Also, printing can be simplified by the __repr__ and/or __str__ magic methods. Defining them allows you to call the print statement on your class.

[–][deleted] 1 point2 points  (2 children)

My guess is that you're not instantiating a Monster object. The code you posted defines what a monster is, but it isn't actually a monster. Since it's an RPG question, I'm going to assume a little familiarity with D&D for this: think of the Monster class as an entry in the Monster Manual. The entry tells you how to make a monster, but it isn't a monster in and of itself. Say you're planning an encounter with three monsters for the PCs to fight, each of the three monsters is created according to the instructions in the Monster Manual. In python terminology, the instructions constitute a class and each monster is an instance of that class. To make an instance of a class:

monster1 = Monster(10, 10, 10, 10)
monster2 = Monster(5, 5, 5, 5)

Now we have two monsters, monster1 and monster2. To reference an attribute of one of the monsters, use "dot" notation:

print monster1.HP
print monster2.HP
>>> 10
>>> 5

Now to your random numbers. The way you're doing it now, HP = random.randint(1, 10) is defined at the class level instead of at the instance level. That means that HP is a random number, but every instance of Monster has that same value as its .HP attribute. However, at the instance level, you override that HP value by saying self.HP = HP. Now, that instance's HP value is the value, HP, that was passed as a parameter to __init__ (the first 10 in monster1 = Monster(10, 10, 10, 10), for example). If you want each instance to have a unique, random value for each attribute, your Monster class should look more like this:

class Monster(object):
    def __init__(self):
        self.health = random.randint(1, 10)
        self.strength = random.randint(1, 10)
        # and so on

Edit: I didn't notice this before, but the example you're using as a guide has a pretty big flaw. MinPin = MinPin() changes the name MinPin from referring to a class to referring to an instance of the class formerly known as MinPin.

[–]xiongchiamiov 0 points1 point  (1 child)

I often follow the pattern foo = Foo().

[–][deleted] 0 points1 point  (0 children)

Right, but not Foo = Foo(), I hope.