Python文本游戏开发:实现自然拾取物品及解决AttributeError报错
问题修复与功能优化方案
一、解决AttributeError及其他代码错误
补全缺失依赖与变量
- 代码使用
sys.stdout但未导入模块,需在开头添加:import sys emptyDescription未定义,需在创建房间前补充:emptyDescription = "This area has nothing noteworthy."
- 代码使用
修正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.")清理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
相关产品推荐
相关产品推荐

