0

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
3
  • 3
    "Not working" is an utterly useless report. What happens, what are you epecting to happen, if there's an error what's the exact message and traceback, etc. Commented Jun 9, 2011 at 14:27
  • 7
    Please tell us what exactly happens. A good way to ask a question is: 1. Background on question 2. What do you expect to happen 3. What happens 4. The code in question Commented Jun 9, 2011 at 14:28
  • @JackMc: Permission to steal that comment and use it? Commented Jun 9, 2011 at 14:38

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you both very much for the comments. I got it working thanks to you guys :)
2

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

2 Comments

@Jochen Real OOP would require you to write a base class Animal from which the Reptiles class is derived, from where you derive the final Snakes class. You might also want to print something when a snake wins the TurnBasedFight (which should be a class derived from Fight, of which RealTimeFight is also derived)
@Jonno_FTW: No, "real" OOP does not mean you write as many classes as you can. Another class to manage the fight with turns and input would just make things a bit easier.
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.