Sean
Sean

Reputation: 3

Python New to Object Oriented Programming

I was wondering how to fix this problem I am having with my first piece of OOP code. The problem lies within the attack method of the Snake class. I have two snakes in the game and am trying to get the snake to attack the other one. At the moment I am using two variables to note which Snake's turn it is, then use this to try and attack the other snake. However this is not working. Anyone have any idea how to solve this? Thank you so much.

class Snake:
    hp=100
    attack=25
    defense=1
    def set_name(self, name):
        self.name=name

    def shed(self):
        self.defense=self.defense+1

    def attack(self, opposite, current):
        opposite.hp=opposite.hp-(current.attack-opposite.defense)

    def eat(self):
        self.attack=self.attack+5
        print(str(self.name) + " eats a rat!")
        print(str(self.name) + "'s attack dmg is now " + str(self.attack))

    def sleep(self):
        print (str(self.name) + " goes to sleep")
        self.hp=self.hp+10
        if self.hp>100:
            self.hp=100
        print (str(self.name) + " wakes up with " + str(self.hp) + "hp")

##initialises the snakes
alpha=Snake()
beta=Snake()
## gives the snakes names of the user's choice
alpha_name=raw_input("What would you like to name your snake? ")
alpha.set_name(alpha_name)
beta_name=raw_input("What would you like to name the other snake? ")
beta.set_name(beta_name)
##starts the game
turn=True
while alpha.hp>0 and beta.hp>0:
    while turn==True:
        opposite="beta"
        current="alpha"
        action=raw_input("attack, sleep, eat or shed? ")
        try:
            if action=="attack":
                alpha.attack(opposite, current)
            if action=="sleep":
                alpha.sleep()
            if action=="eat":
                alpha.eat()
            if action=="shed":
                alpha.shed()

            turn=False
        except IOError:
            print("Please chose only one action, exaclty how it is typed")
    while turn==False:
        opposite="alpha"
        current="beta"
        if beta.hp<15:
            beta.sleep()
        elif alpha.hp>75:
            beta.attack()
        else:
            index=random.randint(1, 3)
            if index==1:
                beta.shed()
            elif index==2:
                beta.eat()
            else:
                beta.attack(opposite, current)    
        turn=True

Upvotes: 0

Views: 321

Answers (3)

Gryphius
Gryphius

Reputation: 78886

in "attack" you try to access "opposite.hp", but this method is called with a string instead of an object:

opposite="alpha"
current="beta"

=> change this to

opposite=alpha
current=beta

also, there is a field and a method with the same name in the class: attack. I suggest renaming the field to "attackpoints" or something.

additionaly, you call "beta.attack()". you forgot the method arguments there.

Upvotes: 2

Chris Adams
Chris Adams

Reputation: 1097

I see two problems. The first is you're passing the name of the variable instead of the variable itself.

change this:

while alpha.hp>0 and beta.hp>0:
    while turn==True:
        opposite="beta"
        current="alpha"
        action=raw_input("attack, sleep, eat or shed? ")
        try:
            if action=="attack":
                alpha.attack(opposite, current)

to this:

while alpha.hp>0 and beta.hp>0:
    while turn==True:
        opposite=beta
        current=alpha
        action=raw_input("attack, sleep, eat or shed? ")
        try:
            if action=="attack":
                alpha.attack(opposite, current)

Additionally, you have the attack field defined twice in the Snake class.

class Snake:
    attack=25

    def attack(self, opposite, current):

Here's what I came up with after playing with your code:

import random

class Snake:
    hp=100
    attack_skill=25
    defense=1

    def set_name(self, name):
        self.name=name

    def shed(self):
        self.defense=self.defense+1

    def attack(self, opposite):
        opposite.hp = opposite.hp - (self.attack_skill - opposite.defense)

    def eat(self):
        self.attack_skill += 5
        print(str(self.name) + " eats a rat!")
        print(str(self.name) + "'s attack dmg is now " + str(self.attack_skill))

    def sleep(self):
        print (str(self.name) + " goes to sleep")
        self.hp=self.hp+10
        if self.hp>100:
            self.hp=100
        print (str(self.name) + " wakes up with " + str(self.hp) + "hp")


##initialises the snakes
alpha=Snake()
beta=Snake()
## gives the snakes names of the user's choice
alpha_name=raw_input("What would you like to name your snake? ")
alpha.set_name(alpha_name)
beta_name=raw_input("What would you like to name the other snake? ")
beta.set_name(beta_name)
##starts the game
turn=True
while alpha.hp>0 and beta.hp>0:
    while turn==True:
        opposite="beta"
        current="alpha"
        action=raw_input("attack, sleep, eat or shed? ")
        try:
            if action=="attack":
                alpha.attack(beta)
            if action=="sleep":
                alpha.sleep()
            if action=="eat":
                alpha.eat()
            if action=="shed":
                alpha.shed()

            turn=False
        except IOError:
            print("Please chose only one action, exaclty how it is typed")
    while turn==False:
        opposite="alpha"
        current="beta"
        if beta.hp<15:
            beta.sleep()
        elif alpha.hp>75:
            beta.attack(alpha)
        else:
            index=random.randint(1, 3)
            if index==1:
                beta.shed()
            elif index==2:
                beta.eat()
            else:
                beta.attack(alpha)
        turn=True

Upvotes: 2

Jonno_FTW
Jonno_FTW

Reputation: 8809

When you beta attack, you are calling the attack() method without any parameters. I assume you want beta.attack(alpha,beta)

But you could probably refactor the method to only require the opponent as a parameter (since you know who is attacking (it's the object calling the attack method))

def attack(self, opposite):
    opposite.hp -= self.attack-opposite.defense

Upvotes: 1

Related Questions