You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python OOP游戏代码故障:Goblin正常,Elf的Hit功能异常

Hey Nathan, let's fix those issues with your Elf class step by step! I spotted two key problems that are causing the "hit elf" command to fail, plus another bug that would crash your game when the Elf's health drops to 1.

1. Case Mismatch in Class Name

Your Elf class sets self.class_name = "Elf" (capital E), but when you type hit elf (lowercase e), the hit function checks if "elf" exists in GameObject.objects—which it doesn't, because the dictionary key is "Elf". This is why the command falls through to the "There is no elf here." message.

2. Undefined Variable in Elf's desc Property

In the Elf class's desc property, when self.health == 1, you reference str(x) but x isn't defined in that branch. This would throw a NameError if the Elf's health ever reaches 1.

Bonus: Minor Optimization Note

Right now, GameObject.objects uses class_name as the key, which means if you ever create multiple instances of the same class, they'll overwrite each other. A better approach would be to use the instance's name or a unique identifier, but since you only have one Elf and one Goblin, this isn't breaking your game right now—just something to keep in mind for future expansion.


Here's the fixed code with comments pointing out the changes:

#importing the random module
import random
#creating the game object class
class GameObject:
    class_name = ""
    desc = ""
    objects = {}
    def __init__(self, name):
        self.name = name
        # Changed: store class name in lowercase for case-insensitive lookups
        GameObject.objects[self.class_name.lower()] = self  
    #defining the description
    def get_desc(self):
        return self.class_name + "\n" + self.desc
#creating the goblin class
class Goblin(GameObject):
    def __init__(self, name):
        self.class_name = "goblin"
        self.health = 3
        self._desc = "A foul creature"
        super().__init__(name)
    @property
    def desc(self):
        if self.health >= 3:
            return self._desc
        elif self.health == 2:
            x = random.randint(13, 35)
            health_line = "You struck and dealt " + str(x) + " damage!"
        elif self.health == 1:
            y = 40 - random.randint(13, 35)
            health_line = "You rushed and dealt " +str(y) + " damage! \n Goblin activated effect Rage!"
        elif self.health <= 0:
            health_line = "It is dead."
        return self._desc + "\n" + health_line
    @desc.setter
    def desc(self, value):
        self._desc = value
#creating the goblin object
goblin = Goblin("Gobbly")
#creating the elf class
class Elf(GameObject):
    def __init__(self, name):
        self.class_name = "Elf"
        self.health = 5
        self._desc = "A strong warlock"
        super().__init__(name)
    @property
    def desc(self):
        if self.health >= 5:
            return self._desc
        elif self.health == 4:
            x = random.randint(20, 50)
            health_line = " You struck and dealt " + str(x) + " damage!"
        elif self.health == 3:
            x = random.randint(20, 40)
            health_line = " You countered and dealt " + str(x) + " damage!"
        elif self.health == 2:
            y = 40 - random.randint(20, 50)
            health_line = "You rushed and dealt " +str(y) + " damage! \n Elf activated effect Sectum Sempra!!"
        elif self.health == 1:
            # Fixed: defined y variable here instead of using undefined x
            y = random.randint(20, 50)  
            health_line = " You struck and dealt " + str(y) + " damage!"
        elif self.health <= 0:
            health_line = "It is dead."
        return self._desc + "\n" + health_line
    @desc.setter
    def desc(self, value):
        self._desc = value
#creating an elf object
elf = Elf("Elfy")
#defining the hit verb
def hit(noun):
    # Changed: convert input noun to lowercase to match stored keys
    noun_lower = noun.lower()
    if noun_lower in GameObject.objects:
        thing = GameObject.objects[noun_lower]
        if type(thing) == Goblin:
            thing.health -= 1
            if thing.health <= 0:
                msg = "You killed the goblin!"
            else:
                msg = "You hit the {}".format(thing.class_name)
        elif type(thing) == Elf:
            thing.health -= 1
            if thing.health <= 0:
                msg = "You killed the elf!"
            else:
                # Optional: lowercase for consistent message
                msg = "You hit the {}".format(thing.class_name.lower())  
        else:
            msg = "There is no {} here.".format(noun)
    else:
        msg = "There is no {} here.".format(noun)
    return msg
#defining the examine verb
def examine(noun):
    # Changed: convert input noun to lowercase for case-insensitive lookups
    noun_lower = noun.lower()
    if noun_lower in GameObject.objects:
        return GameObject.objects[noun_lower].get_desc()
    else:
        return "There is no {} here.".format(noun)
#getting input
def get_input():
    command = input(": ").split()
    verb_word = command[0]
    if verb_word in verb_dict:
        verb = verb_dict[verb_word]
    else:
        print("Unknown verb {}".format(verb_word))
        return
    if len(command) >= 2:
        noun_word = command[1]
        print(verb(noun_word))
    else:
        print(verb("nothing"))
#defining the say verb
def say(noun):
    return 'You said "{}"'.format(noun)
#the verbs
verb_dict = { "say": say, "examine": examine, "hit": hit }
while True:
    get_input()

Key Fixes Explained:

  1. Case-Insensitive Lookups:

    • Modified GameObject.__init__ to store objects using self.class_name.lower() as the key, so both "elf" and "Elf" will match.
    • Updated the hit and examine functions to convert the input noun to lowercase before checking the dictionary, making commands case-insensitive (so hit Elf works too!).
  2. Undefined Variable Fix:

    • In the Elf's desc property, the health == 1 branch now defines y (instead of trying to use x, which only exists in higher health branches) to avoid a NameError.
  3. Consistent Message (Optional):

    • Changed the Elf hit message to use thing.class_name.lower() so it says "You hit the elf" instead of "You hit the Elf" for consistency with the Goblin message.

Now when you type hit elf, it should correctly register the hit and show the feedback message, plus the game won't crash when the Elf's health drops to 1.

内容的提问来源于stack exchange,提问作者nathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:17:37