Python Forum
UnboundLocalErrors: variables reference before assignment? Need Help!
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
UnboundLocalErrors: variables reference before assignment? Need Help!
#1
Brick 
Using Python Version 3.9.1 on Windows 10.

I'm a novice at Python and practicing by making a simple text-based zombie survival game.In its current build, you define your character attributes before fighting off a never-ending horde of zombies.

However, I've come across a couple of errors: one when trying to adjust my in-game stats and when I start the game.

Current game code
# Zombie Survival Sim

import random

def new_player():
    level = 1
    xp = 0
    next_lv = 10 * level
    max_health = 10
    attack = 10
    agility = 10
    aim = 10
    defence = 10
    points = 50
    
    choice = None
    while choice != "quit":
        print(
            """
            YOUR CURRENT STATS
            ##################
            """)
        print(" health: \t\t", max_health, "\t Increase amount of health.")
        print(" attack: \t\t", attack, "\t Increases attack damage.")
        print(" aim: \t\t\t", aim, "\t Increase weapon accuracy.")
        print(" agility: \t\t", agility, "\t Increase % to dodge enemy attacks.")
        print(" defence: \t\t", defence, "\t Reduce damage from enemy attacks.")
        print(" Points left: \t\t", points, "\n")

        print("When you are done, type \"quit\".")
        choice = input("Choose which stat to change: ")
        if choice == "quit":
            print("All done.")
        # health
        elif choice == "health":
            change = None
            while not change:
                change = int(input("How much do you want to change your health? (You can remove points by entering a minus number) : "))
                if change > points:
                    print("No. You don't have enough points to spend.")
                    change = None
                else:
                    health += change
                    if health < 10:
                        health -= change
                        print("Nope. You can't decrease your health any further than 10.")
                        change = None
                    else:
                        print("Your health has been changed by", change)
                        points -= change
        # attack
        elif choice == "attack":
            change = None
            while not change:
                change = int(input("How much do you want to change your attack? (You can remove points by entering a minus number) : "))
                if change > points:
                    print("No. You don't have enough points to spend.")
                    change = None
                else:
                    attack += change
                    if attack < 10:
                        attack -= change
                        print("Nope. You can't decrease your attack any further than 10.")
                        change = None
                    else:
                        print("Your attack has been changed by", change)
                        points -= change
                        
        # aim
        elif choice == "aim":
            change = None
            while not change:
                change = int(input("How much do you want to change your aim? (You can remove points by entering a minus number) : "))
                if change > points:
                    print("No. You don't have enough points to spend.")
                    change = None
                else:
                    aim += change
                    if aim < 10:
                        aim -= change
                        print("Nope. You can't decrease your aim any further than 10.")
                        change = None
                    else:
                        print("Your aim has been changed by", change)
                        points -= change

        # agility
        elif choice == "agility":
            change = None
            while not change:
                change = int(input("How much do you want to change your agility? (You can remove points by entering a minus number) : "))
                if change > points:
                    print("No. You don't have enough points to spend.")
                    change = None
                else:
                    agility += change
                    if agility < 10:
                        agility -= change
                        print("Nope. You can't decrease your agility any further than 10.")
                        change = None
                    else:
                        print("Your agility has been changed by", change)
                        points -= change

        # defence
        elif choice == "defence":
            change = None
            while not change:
                change = int(input("How much do you want to change your defence? (You can remove points by entering a minus number) : "))
                if change > points:
                    print("No. You don't have enough points to spend.")
                    change = None
                else:
                    defence += change
                    if defence < 10:
                        defence -= change
                        print("Nope. You can't decrease your defence any further than 10.")
                        change = None
                    else:
                        print("Your defence has been changed by", change)
                        points -= change
        else:
            print("Invalid choice.")

def level_up():
    health += random.randint(1,10)
    attack += random.randint(1,10)
    agility += random.randint(1,10)
    aim += random.randint(1,10)
    defence += random.randint(1,10)
    print("Health: ", health)
    print("Attack: ", attack)
    print("Aim: ", aim)
    print("Agility: ", agility)
    print("Defence: ", defence)

def zombie_check(zombie_health):
    if zombie_health <= 0:
        message = "The zombie falls dead."
        xp += zombie_xp
    else:
        message = "The zombie is still standing."
    return message

def check_criteria(player,enemy):
    criteria = player - enemy
    great_criteria = criteria / 2
    critical_criteria = criteria / 10
    perfect_criteria = criteria / 100
    return criteria, great_criteria, critical_criteria, perfect_criteria

def phase_defend():
    print("\nZombies attack!")
    zombie_health = 0
    while health > 0:
        if zombie_health <= 0:
            print("\nA zombie appears!")
            zombie_health = random.randrange(10*level)
            zombie_aim = random.randrange(10*level)
            zombie_attack = random.randrange(10*level)
            zombie_agility = random.randrange(10*level)
            zombie_defence = random.randrange(10*level)
            zombie_paces = random.randrange(4)
            zombie_xp = (zombie_health + zombie_aim + zombie_atack + zombie_agility + zombie_defence) / 10

        while zombie_health > 0:
            if zombies_paces <= 0:
                print("\nThe zombie lunges to grab you.")
                success, great, critical, perfect = check_criteria(agility,zombie_aim)
                roll = random.randint(1,100)
                if roll <= perfect:
                    print("You nimbly dodge the zombie and put some distance between you and it!")
                    zombie_paces += 1
                elif roll <= critical:
                    print("You nimbly dodge the zombie and put some distance between you and it!")
                    zombie_paces += 1
                elif roll <= great:
                    print("You nimbly dodge the zombie and put some distance between you and it!")
                    zombie_paces += 1
                elif roll <= success:
                    print("You manage to avoid its grasp!")
                else:
                    print("The zombie grabs hold and bites into your flesh!")
                    damage = zombie_attack - defence
                    health -= damage
                    print("You have", health, "health left.")
            else:
                print("The zombie shambles towards you. It is now", zombie_paces, "paces closer to you.")
                zombie_paces -= 1

            print("\nYou fire a shot at the incoming zombie...")
            success, great, critical, perfect = check_criteria(aim,zombie_agility)
            roll = random.randint(1,100)
            if roll <= perfect:
                print("You land a shot square between the zombies eyes, splattering its head open!")
                zombie_health = 0
                status = zombie_check(zombie_health)
                print(status)
            elif roll <= critical:
                print("You shot the zombie in the head, causing severe damage!")
                damage = attack - zombie_defence
                zombie_health -= damage * 4
                status = zombie_check(zombie_health)
                print(status)
            elif roll <= great:
                print("You shot the zombie in a vital organ, causing greater damage!")
                damage = attack - zombie_defence
                zombie_health -= damage * 2
                status = zombie_check(zombie_health)
                print(status)
            elif roll <= success:
                print("You land a shot and hit the zombie.")
                damage = attack - zombie_defence
                zombie_health -= damage
                status = zombie_check(zombie_health)
                print(status)
            else:
                print("You missed!")

        if xp >= next_lv:
            level += 1
            print("\nLevel up! You are now at level", level, "!")
            level_up()
            

        if health <= 0:
            print("\nYou succumb to your wounds and join the undead...")
                
new_player()
phase_defend()

input("Press ENTER to exit.")
    
First error:
When I try to enter an integer value to spend points to increase or decrease
an in-game stat.

Output:
YOUR CURRENT STATS ################## health: 10 Increase amount of health. attack: 10 Increases attack damage. aim: 10 Increase weapon accuracy. agility: 10 Increase % to dodge enemy attacks. defence: 10 Reduce damage from enemy attacks. Points left: 50 When you are done, type "quit". Choose which stat to change: health How much do you want to change your health? (You can remove points by entering a minus number) : 20
Error:
Traceback (most recent call last): File "E:\My Projects\Python Training\Draft 2\Personal Projects\Zombie Survival Sim\Zombie_Survival_Sim.py", line 229, in <module> new_player() File "E:\My Projects\Python Training\Draft 2\Personal Projects\Zombie Survival Sim\Zombie_Survival_Sim.py", line 43, in new_player health += change UnboundLocalError: local variable 'health' referenced before assignment
Second Error:
Occurs when I enter "quit" in the character creation stage and start the game.
Output:
YOUR CURRENT STATS ################## health: 10 Increase amount of health. attack: 10 Increases attack damage. aim: 10 Increase weapon accuracy. agility: 10 Increase % to dodge enemy attacks. defence: 10 Reduce damage from enemy attacks. Points left: 50 When you are done, type "quit". Choose which stat to change: quit All done. Zombies attack!
Error:
Traceback (most recent call last): File "E:\My Projects\Python Training\Draft 2\Personal Projects\Zombie Survival Sim\Zombie_Survival_Sim.py", line 230, in <module> phase_defend() File "E:\My Projects\Python Training\Draft 2\Personal Projects\Zombie Survival Sim\Zombie_Survival_Sim.py", line 155, in phase_defend while health > 0: UnboundLocalError: local variable 'health' referenced before assignment
Reply
#2
There is no variable named "health" defined in the function "new_player()" when you execute commands like this:
health -= change
Is health defined somewhere else? If so, you need to either pass in the health value or use the global declaration to tell Python that the variable is defined outside of "new_player()".

I'm not going to even look at the second problem as it is probably the same as the first.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Pass by object reference when does it behave like pass by value or reference? mczarnek 2 2,513 Sep-07-2020, 08:02 AM
Last Post: perfringo
  Shared reference of variables... Denial 1 1,373 Aug-29-2020, 01:52 PM
Last Post: snippsat
  How many variables/values are limited to single assignment operator? Prabakaran141 1 2,000 Sep-06-2018, 03:32 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020