Search code examples
pythonpython-3.xloopswhile-loopnested-loops

Python while True loop not iterating over when running my game


Fantasy Battle Game Flowchart

I have been working on this fantasy battle game which is working as expected although the while True loop that starts the game at the very end isn't iterating. I tried using continue with no success. I have included a flow chart to visually show the logic of the game. I'm not getting any error, the loop which should be infinite is just stopping at the end without starting over. Hoe can I make it iterate until it reaches one of the break?

"""
Fantasy Battle Game
Player against Dragon
"""

# Player
wizard = "Wizard"
elf = "Elf"
human = "Human"

# Player health
wizard_hp = 70
elf_hp = 100
human_hp = 150

# Player damage force
wizard_damage = 150
elf_damage = 100
human_damage = 20

# Dragon health and damage force
dragon_hp = 300
dragon_damage = 50

# Print the list of characters
print(wizard)
print(elf)
print(human)

# Input function to choose player
character = input("Choose your character: ")

# While loop to represent player profile
while True:
    if character == "Wizard":
        my_hp = wizard_hp
        my_damage = wizard_damage
        break
    elif character == "Elf":
        my_hp = elf_hp
        my_damage = elf_damage
        break
    elif character == "Human":
        my_hp = human_hp
        my_dammage = human_damage
        break
    else:
        print("Unknown Character")
        break

# Print player selection
print(character)

# print player health:
print(my_hp)

# print player damage force:
print(my_damage)

# Start game
while True:
    # Player start first battle against Dragon
    dragon_hp = dragon_hp - my_damage
    
    # If dragon health is positive show remaining health
    if dragon_hp > 0:
        print(f'{character} damaged the dragon!')
        print(f'The Dragon hitpoints are now {dragon_hp}')
    
    # If dragon health is negative or null - game over
    elif dragon_hp <= 0:
        break
        print(f'The Dragon lost the battle!')
        
    # Dragon start second battle against player
    my_hp = my_hp - dragon_damage
    
    # If player health is positive show remaining health
    if my_hp > 0:
        print(f'The Dragon strikes back at {character}')
        print(f'The {character} hitpoints are now {my_hp}')
        
    # If player health is negative - game over
    elif my_hp <= 0:
        break
        print(f'The {character} lost the battle!')

Solution

  • Your main problem is that you are placing break statements before the print statements, meaning the while loop stops before it reaches the print statements.

    e.g:

        # If dragon health is negative or null - game over
        elif dragon_hp <= 0:
            break #Break should not be here
            print(f'The Dragon lost the battle!')
        # If player health is negative - game over
        elif my_hp <= 0:
            break #Break should not be here
            print(f'The {character} lost the battle!')
    

    Instead, try:

        # If dragon health is negative or null - game over
        elif dragon_hp <= 0:
            print(f'The Dragon lost the battle!')
            break
        # If player health is negative - game over
        elif my_hp <= 0:
            print(f'The {character} lost the battle!')
            break
    

    Also, one tip: you should be using classes for your characters, as it is easier to manage classes. It keeps the characters and their variables together, so you don't have to constantly make more than 1 variable when creating a new character.

    An example for your characters:

    class character:
        def __init__(self,name,damg=0,hp=0):
            self.damage=damg
            self.hp=hp
            self.name=name
    

    You would then create a new character like:

    wizard=character("Wizard",150,70)
    

    Call on each attribute like:

    wizard.hp
    # returns 70
    wizard.name
    # returns "Wizard"
    wizard.damage
    # returns 150
    

    If you keep the characters like this, it means you can run more efficient code, for example I would just out the new character objects in a list, and then put in an attack for loop that iterates over the list of characters and prints out the damage they did, their health, and their name. E.g.

    character_list=[wizard,elf,human] #some imaginary list
    for x in character_list:
        print(f"{x.name} attacked the dragon!")
        print(f"{x.damage} was dealt.")
        print(f"{x.name} has {x.hp} left")
    

    Also, you can edit these as normal. e.g., take our wizard from above:

    # oh no! some event caused your wizard to lose health!
    wizard.hp-=10
    # returns 60 when called again
    

    I hope that was a satisfactory explanation.