0

Ok so i'm making a text based RPG game but i have a issue with python classes that i'm not sure how to fix I've tried looking up this problem but haven't been able to find any posts that pertain to this maybe i'm looking up the wrong things? i don't know. anyways here's my issue i have this class in a file called unit.py in a folder named subfiles

class Enemy(object):
    def __init__(self,name,hp,atk):
        self.name = name
        self.hp = hp
        self.atk = atk

in my main file i have this

from subfiles.unit import *
wolf = Enemy("Wolf", 100, 10)
cow = Enemy("Cow", 50, 0)
NMElist = [wolf,cow]
def gennme():
    global NME
    ##Choose a enemy to fight
    NME = random.choice(NMElist)
def attack():
    NME.hp -= 10
    print NME.hp
attack()

when I run the attack definition it subtracts from the wolf.hp like it should, but that's not exactly what i'm trying to achieve, because the next time a battle comes up against a wolf it will be already dead so how can i have it where wolf = Enemy("Wolf", 100, 10) is just the set out default values and after the battle is over and the wolf is killed, the next time i fight a wolf it loads from the defaults. I hope i'm making sense here i'm sure there's a simple way to achieve this its just evading me perhaps my understanding of how classes work is flawed? anyways I look forward to your responses ans suggestions oh by the way this same thing applies for cow as well as wolf.

Mike Wills
  • 20,959
  • 28
  • 93
  • 149
  • If you fight a different wolf, then you should create a new wolf to fight against. Otherwise, you will keep fighting the same wolf, so when that one is already dead it stays that way. – poke Nov 12 '16 at 23:16

4 Answers4

0

Yeah, maybe it's practice to create a new Wolf after one is killed. But you don't have a alive flag, so is it alive?


You could have the enemy deafult to the deafult hp if the hp is 0. In a manner that lets you check if the wolf is killed. A way to do this:

class Enemy(object):
    def __init__(self,name,hp,atk):
        self.name = name
        self._hp = hp
        self.atk = atk
        self._deafult_hp = hp

    @property
    def hp(self):
        return self._hp

    @hp.setter
    def hp(self, value):
        if not self._hp:
            self._hp = self._deafult_hp
        self._hp = value

Now in the battle you can check if the wolfs hp is 0, and in the next battle the wolfs hp will deafult to the 100 hp or what ever you choose. ^^

Simon
  • 424
  • 4
  • 12
0

You could have separate instances of Enemy created each time a new one is encountered. You can defer creation of the actual instances by wrapping them in a callable:

NMElist = [lambda : Enemy("Wolf", 100, 10),
           lambda : Enemy("Cow", 50, 0)]

This is a simple example of an enemy factory. To get a new random enemy you would need to call the function returned to generate a new cow or wolf:

NME = random.choice(NMElist)()

Note the parentheses () at the end which executes the random enemy factory returned by random.choice to create the actual object. Another layer you could add would be to use inheritance to create Wolf and Cow subclasses of enemy that initialize the proper values, using the super python builtin:

class Enemy(object):
   def __init__(self,name,hp,atk):
       self.name = name
       self.hp = hp
       self.atk = atk

class Wolf(Enemy):
    def __init__(self):
        super(Wolf, self).__init__("Wolf", 100, 10)

class Cow(Enemy):
    def __init__(self):
        super(Cow, self).__init__("Cow", 50, 0)

And then NMElist can contain classes that get instantiated for each enemy encountered

NMElist = [Wolf,Cow]
def gennme():
    global NME
    ##Choose a enemy to fight
    NME = random.choice(NMElist)()
avigil
  • 2,218
  • 11
  • 18
0

Your random function will choose among the already existing uniq objects contained in NMElist (with their previous status)

Intantiating wolf and cow in gennme function may fix this.

from subfiles.unit import *

def gennme():
    global NME
    ##Choose a enemy to fight
    wolf = Enemy("Wolf", 100, 10)
    cow = Enemy("Cow", 50, 0)
    nme_list = [wolf,cow]
    NME = random.choice(nme_list)
def attack():
    NME.hp -= 10
    print NME.hp
attack()

This is far from being the best implementation but It might give you a better understanding of your mistake.

leldo
  • 386
  • 2
  • 9
0

I like Arthur's answer, but another way of doing the same thing is with this:

NMElist = [("Wolf", 100, 10),("Cow", 50, 0)]

Then, inside your gennme() function, select one randomly and pass the values inside of it to the Enemy class:

enemySelection = random.choice(NMElist)
NME = Enemy(*enemySelection)

Basically, this approach would be good if you want to isolate the implementation of the Enemy() class from the values that are associated with the Enemy attributes. Using the * , you can pass the list item values all together as arguments to the Enemy class. By instantiating the enemy at this point, you will be sure to generate another one fresh when the gennme() function is called again.

People answer fast on SO. It took me awhile to work this one out :)

thesis
  • 11
  • 4