The new forums will be named Coin Return (based on the most recent vote)! You can check on the status and timeline of the transition to the new forums here.
The Guiding Principles and New Rules document is now in effect.

Help with Python?

DelzhandDelzhand Registered User, Transition Team regular
edited June 2008 in Help / Advice Forum
I figured I'd check out Python today, and so far, everything is really easy, but I've run into a really strange issue. I come from a more obviously OO background (java/c#), and I'm not sure what's causing this.
import Abilities

class Character:
    def __init__(self, p_name, p_skill):
        self.Name = p_name
        self.Skill = p_skill
        
    HP = 10
    AP = 0
    KnownAttacks = []

    def addAttack(self, p_attack):
        self.KnownAttacks.append(p_attack)
    
    def status(self):
        retval = "%s \nHP: %d   AP: %d" % (self.Name, self.HP, self.AP)
        for atk in self.KnownAttacks:
            retval += "\n%s" % (atk.detail())
        return retval
    
    def modHP(self, p_value):
        self.HP += p_value
        if self.HP > 10:
            self.HP = 10
        if self.HP < 0:
            self.HP = 0
def LoadAbilities():
    abis = []
    abis.append(Abilities.Attack("Slash", 2, "Deal 2 damage to target"))    
    abis.append(Abilities.Attack("Scissor Lock", 2, "Deal 2 damage and disarm target"))
    return abis

def LoadCharacters(p_abilist):
    pcs = []

    Aescher = Entities.Character("Aescher", 8)
    Aescher.addAttack(p_abilist[0])
    pcs.append(Aescher)
    
    Cainas = Entities.Character("Cainas", 7)
    Cainas.addAttack(p_abilist[1])
    pcs.append(Cainas)

    return pcs

print "Starting Ardor Simulator"
abis = LoadAbilities()
pcs = LoadCharacters(abis)
pcs[1].modHP(-1)
for i in pcs:
    print i.status()

The addAttack method of Character is somehow adding the attack to all the instantiations of Character. The code, when run, prints out both characters as having both Slash and Scissorlock. Aside from changing the way Abilities.Attack are created, I'm not sure why this is happening.

Delzhand on

Posts

  • AdrienAdrien Registered User regular
    edited June 2008
    KnownAttacks = [] needs to go in __init__. Outside it's being treated as a member of the class, not of the instances. You can see that if you print Character.KnownAttacks (which shouldn't exist).

    So should HP and AP, really. You'd get the same behavior if they were objects.


    To elaborate a bit since you're new to Python: In Python, everything is an object. This includes classes, and even functions. So in addition to creating new instances with Character(), you can actually address Character itself, or even Character.addAttack. __init__ spawns a new instance of the class, and then returns it automatically. However it won't automatically instantiate every property of the class. You were probably misled by the (seemingly) proper behavior of HP. You don't usually need to think about references in Python, but they're there under the surface. Since HP is an integer, each instance got its own, however they were sharing the same reference to Character's KnownAttacks. You'd notice you also get "proper" behavior by changing addAttack to self.KnownAttacks = [p_attack], which would assign each instance its own unique list.

    Adrien on
    tmkm.jpg
  • DelzhandDelzhand Registered User, Transition Team regular
    edited June 2008
    Okay, that makes sense. (Edit: and that solves the problem, thanks!) But how come pcs[1].modHP(-1) works properly? When I print out the status of the characters, Aescher has 10 HP and Cainas 9. Wouldn't they both have 9 by this logic?

    Delzhand on
  • AdrienAdrien Registered User regular
    edited June 2008
    A minute shy :) See my edit.

    Adrien on
    tmkm.jpg
  • DelzhandDelzhand Registered User, Transition Team regular
    edited June 2008
    Ah, gotcha. Makes sense. Thanks again!

    Delzhand on
Sign In or Register to comment.