尽管已定义,但我一直收到 "undefined"

I keep getting "undefined" although it is defined

我一直收到 'spell' 未定义。

请记住,我对此很陌生。我主要关注 Udemy 中的教程 class。

Traceback (most recent call last):
  File "C:\Users\RealD\PycharmProjects\PythonRPGgame\main.py", line 106, in <module>
    player.reduce_mp(spell.cost)
NameError: name 'spell' is not defined

我在一个单独的 class 文件中定义了 'spell',我已将其导入 main.py 脚本

magic.py

class Spell:
    def __init__(self, name, cost, dmg, type):
        self.name = name
        self.cost = cost
        self.dmg = dmg
        self.type = type

    def generate_damage(self):
        low = self.dmg - 15
        high = self.dmg + 15
        return random.randrange(low, high)

据说错误在这里:

player.reduce_mp(spell.cost)

inventory.py

class Item:
    def __init__(self, name, type, descrip, prop):
        # descrip meaning description
        self.name = name
        self.type = type
        self.descrip = descrip
        self.prop = prop

game.py

import random
from classes.inventory import Item
import pprint

class bcolors:
    HEADER = '3[95m'
    OKBLUE = '3[94m'
    OKGREEN = '3[92m'
    WARNING = '3[93m'
    FAIL = '3[91m'
    ENDC = '3[0m'
    BOLD = '3[1m'
    UNDERLINE = '3[4m'


class Person:
    def __init__(self, hp, mp, atk, df, magic, items):
        self.maxhp = hp
        self.hp = hp
        self.maxmp = mp
        self.mp = mp
        self.atkl = atk - 10
        self.atkh = atk + 10
        self.df = df
        self.magic = magic
        self.items = items
        self.action = ["Attack", "Magic", "Items"]

    def generate_damage(self):
        return random.randrange(self.atkl, self.atkh)

    def heal(self, dmg):
        self.hp += dmg
        if self.hp > self.maxhp:
            self.hp = self.maxhp

    '''def generate_spell_damage(self, i):
        mgl = self.magic[i]["dmg"] - 5
        mgh = self.magic[i]["dmg"] + 5
        return random.randrange(mgl, mgh)'''

    def take_damage(self, dmg):
        self.hp -= dmg
        if self.hp < 0:
            self.hp = 0
        return self.hp

    def get_hp(self):
        return self.hp

    def get_max_hp(self):
        return self.maxhp

    def get_mp(self):
        return self.mp

    def get_max_mp(self):
        return self.maxmp

    def reduce_mp(self, cost):
        self.mp -= cost

    def choose_action(self):
        i = 1
        print("\n" + bcolors.BOLD + bcolors.HEADER + "ACTIONS:" + bcolors.ENDC)
        for item in self.action:
            print("    " + str(i) + ". ", item)
            i += 1

    def choose_magic(self):
        i = 1
        print("\n" + bcolors.OKBLUE + bcolors.BOLD + "MAGIC:" + bcolors.ENDC)
        for spell in self.magic:
            print("    " + str(i) + ". ", spell.name, "(cost:", str(spell.cost) + ")")
            i += 1

    def choose_item(self):
        i = 1

        print("\n" + bcolors.OKGREEN + bcolors.BOLD + "ITEMS:" + bcolors.ENDC)
        for item in self.items:
            print(("    " + str(i)) + ". " , item["item"].name, ":", item["item"].descrip, " (x" + str(item["quantity"]) + ")")
            i += 1

Main.py:

from classes.game import Person, bcolors
from classes.magic import Spell
from classes.inventory import Item
import re


fire = Spell("Fire", 10, 100, "black")
thunder = Spell("Thunder", 10, 100, "black")
blizzard = Spell("Blizzard", 10, 100, "black")
meteor = Spell("Meteor", 10, 100, "black")
quake = Spell("Quake", 14, 140, "black")


cure = Spell("Cure", 12, 120, "white")
cura = Spell("Cura", 18, 200, "white")


potion = Item("Potion", "potion", "Heals 50 HP", 50)
hipotion = Item("Hi-Potion", "potion", "Heals 100 HP", 50)
superpotion = Item("Super Potion", "potion", "Heals 500 HP", 500)
elixer = Item("Elixer", "elixer", "Fully restores HP/MP of one party member", 9999)
hielixer = Item("Super Elixer", "elixer", "Fully restores entire party's HP/MP", 9999)


grenade = Item("Grenade", "attack", "Deals 500 damage", 500)

player_spells = [fire, thunder, blizzard, meteor, quake, cure, cura]
player_items = [{"item": potion, "quantity": 15}, {"item": hipotion, "quantity": 5},
                {"item": superpotion, "quantity": 5},  {"item":elixer, "quantity": 5},
                {"item": hielixer, "quantity": 2}, {"item": grenade, "quantity": 5}]


player = Person(460, 65, 60, 34, player_spells, player_items)
enemy = Person(1200, 65, 45, 25, [], [])






running = True
i = 0



print(bcolors.FAIL + bcolors.BOLD + " AN ENEMY ATTACKS!" + bcolors.ENDC)
print(bcolors.BOLD, bcolors.HEADER + "Press 0 to go back to the previous menu" + bcolors.ENDC)

while running:

    print("===============================")
    player.choose_action()
    choice = input(bcolors.BOLD + "Choose action:" + bcolors.ENDC)
    print("===============================")
    index = int(choice) - 1

    if index == 0:
        dmg = player.generate_damage()
        enemy.take_damage(dmg)
        print("===============================")
        print(bcolors.FAIL + "You attacked for", dmg, "points of damage!" + bcolors.ENDC)
    elif index == 1:
        player.choose_magic()
        magic_choice = int(input("Choose Magic: ")) - 1
        if magic_choice == -1:
            continue

        spell = player.magic[magic_choice]
        magic_dmg = player.magic[magic_choice].generate_damage()

        current_mp = player.get_mp()

        if spell.cost > current_mp:
            print(bcolors.FAIL + "\nNot enough MP\n" + bcolors.ENDC)
            continue

        if spell.type == "white":
            player.heal(magic_dmg)
            print(bcolors.OKBLUE + "\n" + spell.name + "heals for", str(magic_dmg), "HP" + bcolors.ENDC)
        elif spell.type == "black":
            enemy.take_damage(magic_dmg)
            print(bcolors.OKBLUE + "\n" + spell.name + "deals", str(magic_dmg), "points of damage!" + bcolors.ENDC)
    elif index == 2:
        player.choose_item()
        item_choice = int(input("Choose item: ")) - 1

        if item_choice == -1:
            continue

        item = player.items[item_choice]["item"]
        player.items[item_choice]["quantity"] -= 1


        if item.type == "potion":
            player.heal(item.prop)
            print(bcolors.OKGREEN + "\n" + item.name + " heals for", str(item.prop), "HP" + bcolors.ENDC)
        elif item.type == "elixer":
            player.hp = player.maxhp
            player.mp = player.maxmp
            print(bcolors.OKGREEN + "\n" + item.name + " fully restores HP/MP" + bcolors.ENDC)
        elif item.type == "attack":
            enemy.take_damage(item.prop)
            print(bcolors.FAIL + "\n" + item.name + " deals", str(item.prop), " points of damage" + bcolors.ENDC)



        player.reduce_mp(spell.cost)
        enemy.take_damage(magic_dmg)
        print(bcolors.OKBLUE + "\n" + spell.name + " deals", str(magic_dmg), "points of damage!" + bcolors.ENDC)


    enemy_choice = 1

    enemy_dmg = enemy.generate_damage()
    player.take_damage(enemy_dmg)
    print(bcolors.FAIL + "Enemy attacks for", enemy_dmg, "points of damage!" + bcolors.ENDC)

    print("===============================")
    print("Enemy HP:", bcolors.FAIL + str(enemy.get_hp()) + "/" + str(enemy.get_max_hp()) + bcolors.ENDC + "\n")

    print("Your HP:", bcolors.OKGREEN + str(player.get_hp()) + "/" + str(player.get_max_hp()) + bcolors.ENDC + "\n")
    print("Your MP:", bcolors.OKBLUE + str(player.get_mp()) + "/" + str(player.get_max_mp()) + bcolors.ENDC)

    if enemy.get_hp() == 0:
        print(bcolors.OKGREEN + "You won the battle!" + bcolors.ENDC)
        running = False
    elif player.get_hp() == 0:
        print(bcolors.FAIL + "You have died." + bcolors.ENDC)
        running = False

看起来“spell”是在 index == 1 的分支中定义的。但错误来自 index == 2 的分支。如果先采用该分支,那么此时 spell 仍将是未定义的.

我怀疑问题行错位了,当你使用了一个物品时你不应该收取法术费用。

我已经弄明白了。我需要下面的代码

spell = player.magic[magic_choice]