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

Python文本游戏开发:实现自然拾取物品及解决AttributeError报错

问题修复与功能优化方案

一、解决AttributeError及其他代码错误

  1. 补全缺失依赖与变量

    • 代码使用sys.stdout但未导入模块,需在开头添加:
      import sys
      
    • emptyDescription未定义,需在创建房间前补充:
      emptyDescription = "This area has nothing noteworthy."
      
  2. 修正Drop功能逻辑错误
    原代码存在变量未定义、循环逻辑混乱问题,修正后:

    # Drop Item
    if action.lower().startswith('drop'):
        parts = action.split(maxsplit=1)
        if len(parts) < 2:
            ask = input('What would you like to drop? \n')
        else:
            ask = parts[1]
        found = False
        # 用copy()避免遍历中修改列表引发异常
        for item in player.inventory.copy():
            if item.name.lower() == ask.lower():
                print(f'You drop the {item.name}.')
                player.inventory.remove(item)
                player.location.items.append(item)
                found = True
                break
        if not found:
            print("You don't have that item.")
    
  3. 清理Pickup功能的无效循环
    原代码嵌套循环覆盖ask变量,导致逻辑混乱,这是引发异常的核心原因之一,后续优化将彻底重构该部分。

二、实现完整指令支持(如pickup shovel)

重构输入解析逻辑,拆分动作与目标物品,无需二次询问:

# Pick up Item
pickup_commands = ['pickup', 'get', 'take']
action_lower = action.lower()
if any(action_lower.startswith(cmd) for cmd in pickup_commands):
    # 拆分输入为动作和目标,maxsplit=1避免物品名含空格时被拆分
    parts = action.split(maxsplit=1)
    if len(parts) < 2:
        ask = input('What would you like to pick up? \n')
    else:
        ask = parts[1]
    
    # 在房间物品中查找目标
    target_item = None
    for item in player.location.items.copy():
        if item.name.lower() == ask.lower():
            target_item = item
            break
    
    if target_item:
        if target_item.equipable:
            print(f"\nYou have picked up a {target_item.name}\n")
            print(f"{target_item.description}\n")
            player.location.items.remove(target_item)
            player.inventory.append(target_item)
        else:
            print("You can't pick up this item.")
    else:
        print("That item isn't here.")

三、完整修正后的代码

import sys

class Room(object):
    def __init__(self, name, description):
        self.name = name
        self.description = description
        self.exits = {}
        self.items = []

class Player(object):
    def __init__(self, name, location):
        self.name = name
        self.location = location
        self.inventory = []
        self.gameOver = False

class Item(object):
    def __init__(self, name, description, equipable, attackBonus, damage):
        self.name = name
        self.description = description
        self.equipable = equipable
        self.attackBonus = attackBonus
        self.damage = damage 

# 定义缺失变量
emptyDescription = "This area has nothing noteworthy."

# 创建物品
shovel = Item('Shovel', 'You find a sturdy shovel. It looks like it could do some good bashing.', True, 1, 2)
rockingChair = Item('Old Rocking Chair', "A rickety old rocking chair sits covered in grime. It doesn't look very appealing.", False, 0, 0)
stick = Item('Stick', 'You find a fragile looking stick, it looks like it could break easily.', True, 0, 0)

# 创建场景
YourHouse = Room("Your House", "There isn't anything new here.")
TownHall = Room("Town Hall", "")
TownHall.items.append(shovel)
TownHall.items.append(rockingChair)
TownHall.items.append(stick)
Park = Room("Park", "There are some lovely green trees next to a small pond.")

# 设置场景出口
YourHouse.exits = {"north": TownHall, "west": Park}
TownHall.exits = {'south': YourHouse}

# 创建玩家
player = Player('You are the Player', YourHouse)

# 启动游戏
print('\n' + player.location.name)
print(player.location.description)
room_exits = "\nThe exits are: \n"
for character in room_exits:
    sys.stdout.write(character)
    sys.stdout.flush()
for exit_dir in player.location.exits:
    print(exit_dir)

while player.gameOver is False:
    # 获取玩家输入
    action = input('>').strip()

    # 移动逻辑
    if action.lower() in ['north', 'south', 'east', 'west']:
        if action in player.location.exits:
            player.location = player.location.exits[action]
            print(f"\nYou went to {player.location.name}.")
            print(player.location.description if player.location.description else emptyDescription)
        else:
            print("You can't go that way.")

    # 丢弃物品逻辑
    if action.lower().startswith('drop'):
        parts = action.split(maxsplit=1)
        if len(parts) < 2:
            ask = input('What would you like to drop? \n').strip()
        else:
            ask = parts[1]
        found = False
        for item in player.inventory.copy():
            if item.name.lower() == ask.lower():
                print(f'You drop the {item.name}.')
                player.inventory.remove(item)
                player.location.items.append(item)
                found = True
                break
        if not found:
            print("You don't have that item.")

    # 检查场景物品逻辑
    if action.lower() in ['examine', 'check', 'look']:
        if player.location.items:
            print("\nYou see the following items:")
            for item in player.location.items:
                print(f'- {item.name}')
        else:
            print("\nThere are no items here.")

    # 拾取物品逻辑
    pickup_commands = ['pickup', 'get', 'take']
    action_lower = action.lower()
    if any(action_lower.startswith(cmd) for cmd in pickup_commands):
        parts = action.split(maxsplit=1)
        if len(parts) < 2:
            ask = input('What would you like to pick up? \n').strip()
        else:
            ask = parts[1]
        
        target_item = None
        for item in player.location.items.copy():
            if item.name.lower() == ask.lower():
                target_item = item
                break
        
        if target_item:
            if target_item.equipable:
                print(f"\nYou have picked up a {target_item.name}\n")
                print(f"{target_item.description}\n")
                player.location.items.remove(target_item)
                player.inventory.append(target_item)
            else:
                print("You can't pick up this item.")
        else:
            print("That item isn't here.")

    # 查看背包逻辑
    if action.lower() in ['inventory', 'inv', 'item', 'items']:
        if player.inventory:
            print("Your items are: ")
            for item in player.inventory:
                print(f'- {item.name}')
        else:
            print("Your inventory is empty.")

    # 退出游戏逻辑
    if action.lower() == 'exit':
        player.gameOver = True

四、关键优化点说明

  • 输入解析:用split(maxsplit=1)拆分动作与目标,支持带空格的物品名(如pickup Old Rocking Chair)。
  • 安全遍历:遍历列表时使用copy(),避免修改列表时引发遍历异常。
  • 容错提示:为空场景、无物品、无效方向等情况添加友好反馈。
  • 流畅交互:直接识别pickup shovel类完整指令,无需二次询问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:52:05