Ah! Never mind! I forgot you could embed classes such as:

class Heroes():
    class Lords():
        class Phill():
            hp = 25
>>> Heroes.Lords.Phill.hp
25

------------------------------------------------------

I am attempting to write an RPG in Python. I am not worrying about the battle system or mapping quite yet, and am more focused on the internal variable handling. My biggest concern is not how to set each variable, but how to format my code to make this as efficient as possible.

Is it better practice to create a class for the heroes and then a function for each hero? Or is a class for the heroes and then a function for "stats" and "attributes" a better way to go, addressing these functions for each hero specifically? For example:

class Hero(heroID, heroClass):
	def Stats(heroID)
		maxHP = 0
		maxMP = 0
		atk = 0
		res = 0    # res = defense
		mres = 0
		spd = 0
		ski = 0
	def Attributes(heroClass)
		mountedUnit = 0
		flyingUnit = 0
		walkOnWater = 0
		canUseSword = 0
		canUseLance = 0
		canUseAxe = 0
		canUseBow = 0
		canUseLightMagic = 0
		canUseDarkMagic = 0
		canUseStaves = 0
		canUseLockpick = 0

or

class Hero():
	def Phill():
		heroClass = classDict[0]	# Lord class
		startLvl = 1
		mountedUnit = 0			
		flyingUnit = 0
		walkOnWater = 0
		canUseSword = 1
		canUseLance = 1
		canUseAxe = 0
		canUseBow = 0
		canUseLightMagic = 0
		canUseDarkMagic = 0
		canUseStaves = 0
		canUseLockpick = 0
		
	def Ork():
		heroClass = classDict[1]	# Knight class
		startLvl = 3
		mountedUnit = 1
		flyingUnit = 0
		walkOnWater = 0
		canUseSword = 1
		canUseLance = 1
		canUseAxe = 0
		canUseBow = 0
		canUseLightMagic = 0
		canUseDarkMagic = 0
		canUseStaves = 0
		canUseLockpick = 0

If I were to use the class Hero() ... def Stats() ... def Attributes() method, how do I address each variable from inside of a class/function? For example, how do I manipulate maxHP or canUseSword for each hero individually? I'm looking for something along the lines of:

Hero.Stats.maxHP(Phill) = 25
Hero.Stats.atk(Phill) = 15
Hero.Stats.res(Phill) = 10
damage = (Hero.Stats.atk(heroName) * 2) - (Enemy.Stats.res(enemyName) * 1.5)

I am new-ish to Python programming, as I used to be a lot better with the language, but gave it up for a long time. I'm going to use this RPG as a method of relearning the language and sharpening my programming skills in general.

Thanks for your time,
Alex

Edited 5 Years Ago by linux: n/a

Why is this solved? lol.

I was handling the handling of variables (Until my 3rd computer wipe, which caused me to stop working on my RPG) like so

class Hero:
    """The hero class"""
    def __init__(self, name, id, race, stats, level=1):
        """ Creates the Hero"""
        self.name = name # Sets the name
        self.id = id # Sets the ID
        self.race = race # Sets the race (orc or human or etc)
        self.stats = stats # Sets the stats
        self.level = level # Sets the level

Then you can just do this

Phil = Hero('Phil', 1, "Human", {'atk':1, 'magic':5})
# Access things with
Phil.level # Gets his level
Phil.stats['atk'] # Gets his attack
# etc

And if you wanted, you could even throw all the Heros into an array

hero_list = [Phil, Hero('Orc', 2, 'Orc', {'Orc Power':1234}, 8)
for hero in hero_list:
    print hero.level # prints 1 for phil, 8 for orc
Comments
Better design

It's solved because I answered my own question. I created a class for each class (no pun intended).

class Hero():
	class Lords():
		class Attributes():
			movement = 5
			mountedUnit = 0
			flyingUnit = 0
			walkOnWater = 0
			canUseSword = 1
			canUseLance = 1
			canUseAxe = 0
			canUseBow = 0
			canUseLightMagic = 0
			canUseDarkMagic = 0
			canUseStaves = 0
			canUseLockpick = 0
		class Phill():		# Main hero
			inventory = (Dictionary.itemDict[1], 0, 0, 0, 0)	# Steel Sword equipped by default
			name = Phill
			class Stats():
				startLvl = 1
				Lvl = 1
				XP = 0			# out of 100
				maxHP = 18		# at level 1
				HP = 18			# remaining HP
				maxMP = 4		# at level 1
				MP = 4			# remaining MP
				atk = 5			# Attack
				res = 5			# Physical resistance (defense)
				mres = 3		# Magic resistance 
				spd = 5			# Speed
				skill = 5		# Accuracy = ((skill*2)*luck)
				luck = 5
				dex = 5			# Influences crit ratio

This way, Hero.Lords.Phill.Stats.Lvl would yield 1.

It would not yield one. You declare a bunch of local variables and do nothing with them. In fact, you'd get an error.

First, you'd have to declare the class Hero. Then inside Hero, you'd have to declare an instance of Lords. Inside Lords, you'd have to declare an instance of Phil. Inside Phil, you'd have to declare an instance of Stats and an instance of Attributes.
Then if you tried to get the level variable, you'd get an error, because there is no 'Lvl' variable associated with Phil.

You could add a hierarchy of classes

class Hero:
    # contains methods common to all heroes
    ...

class Lord(Hero):
    # contains methods specific to Lords
    ...

class MainHero(Lord):
    # contains main hero specific methods
    ...

phill = MainHero(...)

Don't nest classes, it is more annoying than useful. Write all your classes at module level (unless you define functions which create new classes).

well as Grib is found of helping....
I like his idea. basics will work like this....

class Hero:
   def __init__(self,name,size,strenght):
         self.name=name
         self.size=size
         self.strenght=strenght
   def foo(self):
        pass
    # contains methods common to all heroes
    ...

class Lord(Hero):
    def __init__(self,foo,bar):
      Hero.__init__(self,foo,bar)
      pass
    # contains methods specific to Lords
    ...

class MainHero(Lord):
      def __init__(self,foo,bar):
         Lord.__init__(self,foo,bar)
         pass
    # contains main hero specific methods
    ...

phill = MainHero(...)
phill.foo()   # That you cant call methods in other classes bases on inherintace

Very simple idea. But dont next classes like that. Very scary idea.
:)

This article has been dead for over six months. Start a new discussion instead.