Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Object-Oriented Python (retired) Hack-n-Slash The Final Push

Argh! Undead monsters!

My game starts off just fine, but once I kill the first monster things go wonky. The cleanup method appears to run; I get the message and the experience added to my character. But the monster keeps on attacking, even continuing into negative hit points.

Here's the code from my game.py file. Let me know if the other files are pertinent, but it seems like the error is somewhere in either the cleanup method or the get_next_monster method.

import sys

from character import Character
from monster import Dragon
from monster import Goblin
from monster import Troll


class Game:
    def setup(self):
        self.player = Character()
        self.monsters = [
          Goblin(),
          Troll(),
          Dragon()
        ]
        self.monster = self.get_next_monster()

    def get_next_monster(self):
        try:
            return self.monsters.pop(0) # Will take first monster in list
        except IndexError: # if list is empty
            return None # None is falsey, but is only ever equal to None (not 0 or False)

    def monster_turn(self):
        # check to see if monster attacks
        if self.monster.attack():
            # if so, tell player
            print("{} attacks you!".format(self.monster))
            # Check to see if player wants to dodge
            if not input("Dodge? Y/n ").lower() == 'n':
            # if so, see if dodge is successful
                if self.player.dodge():
                # if it is, move on
                   print("You dodged the attack.")
                # it it's not, remove one player hit point.
                else:
                    print("You got hit anyway.")
                    self.player.hit_points -= 1
            else:
                print('''{} lunges at you with a powerful "{}!"'''.format(self.monster, self.monster.sound.upper()))
                self.player.hit_points -= 1
        # if monster isn't attacking, tell player
        else:
            print('''The {} roars at you. "{}!" But it's attack misses!'''.format(self.monster, self.monster.sound.upper()))

    def player_turn(self):
        # let player attack, rest, or quit
        action = input("Do you want to [A]ttack, [R]est, or [Q]uit? ").lower()
        # if they attack:
        if action == 'a':
            # see if attack is successful
            print("You attack {} with your {}!".format(self.monster, self.player.weapon))
            if self.player.attack():
                # If so, see if monster dodges
                if self.monster.dodge():
                    # if dodged, print that
                    print("{} dodged your attack!".format(self.monster))
                    # if not dodged, subtract hit points from monster
                else:
                    if self.player.leveled_up():
                        self.monster.hit_points -= 2
                    else:
                        self.monster.hit_points -= 1

                    print("You hit {} with your {}!".format(self.monster, self.player.weapon))
            # if attack misses, tell player
            else:
                print("You missed!")

        # if they rest:
        elif action == 'r':
            # Call the player.rest() method
            self.player.rest()
        # if they quit, exit game
        elif action == 'q':
            print("Big baby.")
            sys.exit()
        # if they pick anything else, re-run this method.
        else:
            self.player_turn()

    def cleanup(self):
        if self.monster.hit_points <= 0:
            self.player.experience += self.monster.experience
            print("You have defeated {}!".format(self.monster))
            self.get_next_monster()

    def __init__(self):
        self.setup()

        while self.player.hit_points and (self.monster or self.monsters):
            print('\n' + '='*20)
            print(self.player)
            self.monster_turn()
            print('-'*20)
            self.player_turn()
            self.cleanup()
            print('\n' + '='*20)

        if self.player.hit_points:
            print("You win!")
        elif self.monsters or self.monster:
            print("You lose!")
        sys.exit()

Game()

By the way Kenneth Love , Python is love. Python is life. Thank you for these courses, they are great!

2 Answers

Kenneth Love
STAFF
Kenneth Love
Treehouse Guest Teacher

You aren't ever deleting the monster when you kill it.

Ah, yes, I see what I missed! I didn't set self.monster to the get_next_monster method in my cleanup! Thanks!