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

The while loop is not breaking once my player's hitpoints <= 0?

Everything seems to be working pretty well except that the while loop just continues even after my players health is 0 or less. Not sure why this is happening but all help would be greatly appreciated!

Here's the code:

import sys
import random
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 = random.choice(self.monsters)

    def type_of_monster(self):
        if self.monster.__class__.__name__ == "Goblin":
            self.monster_turn(1, "")
        elif self.monster.__class__.__name__ == "Troll":
            self.monster_turn(3, "s")
        elif self.monster.__class__.__name__ == "Dragon":
            self.monster_turn(5, "s")

    def get_next_monster(self):
        self.monsters.remove(self.monster)
        self.monster = random.choice(self.monsters)


    def monster_turn(self, num, string):
        if self.monster.attack(): 
            print("{} is attacking!".format(self.monster))
            want_to_dodge = input("Dodge? Y/n ").lower()
            if want_to_dodge == "y":
                self.player.dodge()
                if self.player.dodge():
                    print("You dodged the {} attack!".format(self.monster.__class__.__name__))
                else:
                    self.player.hit_points -= num
                    print("You got hit anyway! HP: {}".format(self.player.hit_points))

            else:
                print("{} hit you for {} point{}!".format(self.monster, num, string))
                self.player.hit_points -= num
        else:
            print("{} is not attacking you this turn.".format(self.monster)) 

    def player_turn(self):
        player_move = input("[A]ttack, [R]est, or [Q]uit? ").lower()

        if player_move == "a":
            print("You're attacking {}.".format(self.monster))
            self.player.attack()

            if self.player.attack():
                self.monster.dodge()
                if self.monster.dodge():
                    print("{} dodged your attack!".format(self.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))
            else:
                print("You missed!")
        elif player_move == "r":
            self.player.rest()
        elif player_move == "q":
            sys.exit()
        else:
            self.player_turn()

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

    def __init__(self):
        self.setup()
        while self.player.hit_points >= 0 and (self.monster or self.monsters):
            print("\n" + "=" * 20)
            print(self.player)
            self.type_of_monster()
            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()

Note: Added code block formatting.

1 Answer

Steven Parker
Steven Parker
243,215 Points

This code is dependent on other modules not shown.

So it wasn't possible to run the program and replicate the issue. But just looking over it, I noticed a few peculiar things:

  • after the loop ends, winning is determined by if self.player.hit_points: — so negative points would "win".
  • in several places, a method call is made (on its own), but then made again as part of an if condition.

Here's an example of the latter issue:

        self.player.attack()     # this calls the method
        if self.player.attack(): # this calls the same method again