Python 3:如何从基于文本的游戏中的库存中删除项目?
Python 3: How to remove items from an inventory in a text-based game?
我一直在开发一款类似 Zork 的基于文本的冒险游戏,作为个人项目 "Crash course" 自学 python。我是一般编码的新手,所以我对基础知识很模糊。
我已经在我的游戏中成功导航我创建的地图,并且可以自由添加新的 rooms/items。我目前正在努力使 "Inventory" 系统正常工作。
目前,我的房间 class 中有一本名为 "roominv" 的字典,用作每个特定房间的清单。我在播放器 class 中也有一个名为 "bag" 的字典,用作播放器清单。
目前游戏存在问题且未完成,因此要拾取物品,您必须拾取当前房间中的所有物品,但这不是我遇到的问题。
我不知道如何在玩家拿起那个房间里的物品后清空 roominv 字典。现在我可以将物品添加到玩家包中,但它会创建一个副本而无需将它们从 roominv 中移除。
我试过使用 del、delattr 和 pop,但要么我没有正确使用它们(这是我假设的),要么这不是正确的方法。我也尝试了 .remove 我留在下面的代码中。它 returns 这个错误信息
Traceback (most recent call last):
File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 104, in <module>
player = Player("Jeff", 100, [], 'introd', command)
File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 97, in __init__
addToInventory(self.room.roominv)
File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 82, in addToInventory
Room.roominv.remove(item)
AttributeError: type object 'Room' has no attribute 'roominv'
这与使用 del 或 delattr 时出现的错误相同。
任何提示、建议或伪代码将不胜感激,如果我只是以完全错误的方式解决这个问题,请告诉我哈哈。
要开始游戏,您必须输入 n、w、e 或 s 3 次(错误),然后您可以使用这些键四处走动或使用 [=35= 在房间中拾取物品].
world = {}
command = input('>>> ')
class Items:
def __init__(self, name, info, weight, position):
self.name = name
self.position = position
self.info = info
self.weight = weight
class Weapon(Items):
def __init__(self, name, info, damage, speed, weight, position):
super().__init__(name, info, weight, position)
self.damage = damage
self.speed = speed
sword = Weapon("Sword", "A sharp looking sword. Good for fighting goblins!", 7, 5, 5, 0)
knife = Weapon("Knife", "A wicked looking knife, seems sharp!", 5, 7, 3, 5)
stick = Weapon("Stick", "You could probably hit someone with this stick if you needed to", 2, 3, 3, 2)
shackkey = Items("Shack Key", "A key! I wonder what it opens.", .01, 3)
cottagekey = Items("Cottage Key", "An ornate key with an engraving of a small cottage on one side", .01, 5)
Moonstone = Items("Moonstone", "A smooth white stone that seems to radiate soft white light", .05, 6)
flower = Items("Flower", "A beautiful wildflower", .001, 1)
class Room:
def __init__(self, name, description, exits, actions, roominv): # Runs every time a new room is created
self.name = name
self.description = description
self.exits = exits
self.actions = actions
self.roominv = roominv
world['introd'] = Room('introd', "You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.", {'n' or 'north' or 'go north': "clearing"}, {"Search the ground", "Go North"}, {'sword': sword})
world['clearing'] = Room('clearing', "You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. \
To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.", {'s' or 'south' or 'go south': "introd", 'e' or 'east' or 'go east': "forest path"}, {"Take flower", "Go south", "Go East"}, {'flower': flower})
class Player:
def __init__(self, name, health, bag, room_name, move):
self.name = name
self.health = health
self.bag = bag
self.room = world[room_name]
self.move = move
def travel(self, direction):
if direction not in self.room.exits.keys():
print("You can't go that way!")
else:
new_room_name = self.room.exits[direction]
print("moving to", new_room_name)
self.room = world[new_room_name]
print(self.room.description)
print(self.room.actions)
def addToInventory(item):
self.bag.append(item)
Room.roominv.remove(item)
command = input('>>> ')
while command != "":
command = input('>>> ')
if command in {'n', 'e', 's', 'w', 'north', 'south', 'east', 'west', 'go north', 'go south', 'go east', 'go west'}:
travel(self, command)
elif command == 'look':
print(self.room.description)
print('Exits', self.room.exits.keys())
elif command == '':
print('You have to say what it is you want to do! Unfortunately due to a bug you must now restart the game. We are working on fixing this as soon as possible. Sorry!')
elif command == 'search':
print(self.room.roominv)
elif command == 'Take Items':
addToInventory(self.room.roominv)
elif command == 'Inventory':
print(self.bag)
else:
print('Invalid command')
player = Player("Jeff", 100, [], 'introd', command)
也欢迎大家批评我的代码!我正在努力学习,任何来自更有经验的人的 advice/comments 都会很棒。
你的addInventory
方法是错误的。首先,您必须使用实例变量 self.room
而不是 class Room
本身。其次,如果你想要清理整个 roominv
字典,你应该尝试:
def addToInventory(item):
self.bag.append(item)
self.room.roominv.clear() # this will clear the roominv dictionary
更新
如果你想从 roominv 中删除单个元素,你可以这样做:
self.room.roominv.pop(key, None)
如果键不在字典中,None
将防止 pop 引发 KeyError
little_birdie 说得对,您正在尝试访问 class room
的属性,而不是获取 Room
.[= 的实例之一20=]
此外你的 roominv
是 dict
。只有 list
获得了方法 remove()
。
要从字典中删除键,请使用:
del dict_name[key]
我刚看到,您不仅要挑选单个商品,而且要一次性挑选所有商品。
因此你可以使用:
self.room.roominv.clear()
Here is a little example 这可能会帮助您完成工作。
您可能想要做的是这样的事情:
def addToInventory(item):
self.bag.append(item)
del self.room.roominv.clear()
虽然不是代码审查,但我也会添加一些提示来修复您的其他错误,但首先,手头的问题:
Room.roominv.remove(item)
Room
是一个 class,不是一个对象,所以你不能请求它的 roominv
相反,您需要 self.room.roominv
,但是这不会起作用,因为 .remove
不是 dict
的成员,我建议进行以下更改:
您的 'Take Items'
命令应该是:
elif command.split()[0] == 'Take':
for key in list(self.room.roominv.keys()):
if self.room.roominv[key].name == command.split()[1]:
addToInventory(key)
这将允许用户只拿取可用的特定物品,并允许用户指定他们想要取走的物品。
然后你的addToInventory
函数可以是:
def addToInventory(self,key):
self.bag.append(self.room.roominv[key])
del self.room.roominv[key]
如果房间中有多个项目,这将只删除给定的项目。
del
关键字从字典中删除给定的 key/item 对。
关于你的其他问题,你的错误在这里:
elif command == '':
print('You have to say what it is you want to do! Unfortunately due to a bug you must now restart the game. We are working on fixing this as soon as possible. Sorry!')
只需更改 command
的内容即可修复:
elif command == '':
print('You have to say what it is you want to do!')
command = '#'
为了解决您需要多次输入指令的问题,我建议您执行以下操作:
从您的代码顶部删除 command = input('>>> ')
。
将 while command != ""
循环上方的 command = input('>>> ')
替换为 command = ' '
并更新您的 Player
以不使用 move
(这意味着编辑 __init__
函数以及在 player
底部的初始创建您的代码:player = Player("Jeff", 100, [], 'introd')
)
最后,吹毛求疵,为什么不把你的 while
循环放在一个函数中呢?,所有这些导致:
class Player:
def __init__(self, name, health, bag, room_name):
self.name = name
self.health = health
self.bag = bag
self.room = world[room_name]
def travel(self, direction):
if direction not in self.room.exits.keys():
print("You can't go that way!")
else:
new_room_name = self.room.exits[direction]
print("moving to", new_room_name)
self.room = world[new_room_name]
print(self.room.description)
print(self.room.actions)
def addToInventory(self, key):
self.bag.append(self.room.roominv[key])
del self.room.roominv[key]
def play(self):
command = " "
while command != "":
command = input('>>> ')
if command in {'n', 'e', 's', 'w', 'north', 'south', 'east', 'west', 'go north', 'go south', 'go east', 'go west'}:
self.travel(command)
elif command == 'look':
print(self.room.description)
print('Exits', self.room.exits.keys())
elif command == '':
print('You have to say what it is you want to do!')
command = '#'
elif command == 'search':
print(self.room.roominv)
elif command.split()[0] == 'Take':
itemTaken = False
for key in list(self.room.roominv.keys()):
if self.room.roominv[key].name == command.split()[1]:
self.addToInventory(key)
itemTaken = True
if not itemTaken:
print("I can't find that")
elif command == 'Inventory':
print(self.bag)
else:
print('Invalid command')
player = Player("Jeff", 100, [], 'introd')
player.play()
这些更改会导致需要进行一些其他更改,例如在查看您的库存时,打印出每个项目的 .name
,而不是对象本身。
还可以通过完整的代码审查进行更多更改,但是为此您应该 post 在 Code Review 上编写代码,请注意,代码审查只能用于 完整的工作代码,所以在post进入之前确保其中没有任何破坏游戏的错误。
一个例子运行:
>>> n
moving to clearing
You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
{'Go East', 'Take flower', 'Go south'}
>>> s
moving to introd
You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
{'Search the ground', 'Go North'}
>>> n
moving to clearing
You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
{'Go East', 'Take flower', 'Go south'}
>>> s
moving to introd
You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
{'Search the ground', 'Go North'}
>>> search
{'sword': <__main__.Weapon object at 0x00000000040B9470>}
>>> Take sword
I can't find that
>>> Take Sword
>>> Inventory
[<__main__.Weapon object at 0x00000000040B9470>]
>>> search
{}
>>>
我一直在开发一款类似 Zork 的基于文本的冒险游戏,作为个人项目 "Crash course" 自学 python。我是一般编码的新手,所以我对基础知识很模糊。
我已经在我的游戏中成功导航我创建的地图,并且可以自由添加新的 rooms/items。我目前正在努力使 "Inventory" 系统正常工作。
目前,我的房间 class 中有一本名为 "roominv" 的字典,用作每个特定房间的清单。我在播放器 class 中也有一个名为 "bag" 的字典,用作播放器清单。
目前游戏存在问题且未完成,因此要拾取物品,您必须拾取当前房间中的所有物品,但这不是我遇到的问题。
我不知道如何在玩家拿起那个房间里的物品后清空 roominv 字典。现在我可以将物品添加到玩家包中,但它会创建一个副本而无需将它们从 roominv 中移除。
我试过使用 del、delattr 和 pop,但要么我没有正确使用它们(这是我假设的),要么这不是正确的方法。我也尝试了 .remove 我留在下面的代码中。它 returns 这个错误信息
Traceback (most recent call last):
File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 104, in <module>
player = Player("Jeff", 100, [], 'introd', command)
File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 97, in __init__
addToInventory(self.room.roominv)
File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 82, in addToInventory
Room.roominv.remove(item)
AttributeError: type object 'Room' has no attribute 'roominv'
这与使用 del 或 delattr 时出现的错误相同。 任何提示、建议或伪代码将不胜感激,如果我只是以完全错误的方式解决这个问题,请告诉我哈哈。
要开始游戏,您必须输入 n、w、e 或 s 3 次(错误),然后您可以使用这些键四处走动或使用 [=35= 在房间中拾取物品].
world = {}
command = input('>>> ')
class Items:
def __init__(self, name, info, weight, position):
self.name = name
self.position = position
self.info = info
self.weight = weight
class Weapon(Items):
def __init__(self, name, info, damage, speed, weight, position):
super().__init__(name, info, weight, position)
self.damage = damage
self.speed = speed
sword = Weapon("Sword", "A sharp looking sword. Good for fighting goblins!", 7, 5, 5, 0)
knife = Weapon("Knife", "A wicked looking knife, seems sharp!", 5, 7, 3, 5)
stick = Weapon("Stick", "You could probably hit someone with this stick if you needed to", 2, 3, 3, 2)
shackkey = Items("Shack Key", "A key! I wonder what it opens.", .01, 3)
cottagekey = Items("Cottage Key", "An ornate key with an engraving of a small cottage on one side", .01, 5)
Moonstone = Items("Moonstone", "A smooth white stone that seems to radiate soft white light", .05, 6)
flower = Items("Flower", "A beautiful wildflower", .001, 1)
class Room:
def __init__(self, name, description, exits, actions, roominv): # Runs every time a new room is created
self.name = name
self.description = description
self.exits = exits
self.actions = actions
self.roominv = roominv
world['introd'] = Room('introd', "You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.", {'n' or 'north' or 'go north': "clearing"}, {"Search the ground", "Go North"}, {'sword': sword})
world['clearing'] = Room('clearing', "You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. \
To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.", {'s' or 'south' or 'go south': "introd", 'e' or 'east' or 'go east': "forest path"}, {"Take flower", "Go south", "Go East"}, {'flower': flower})
class Player:
def __init__(self, name, health, bag, room_name, move):
self.name = name
self.health = health
self.bag = bag
self.room = world[room_name]
self.move = move
def travel(self, direction):
if direction not in self.room.exits.keys():
print("You can't go that way!")
else:
new_room_name = self.room.exits[direction]
print("moving to", new_room_name)
self.room = world[new_room_name]
print(self.room.description)
print(self.room.actions)
def addToInventory(item):
self.bag.append(item)
Room.roominv.remove(item)
command = input('>>> ')
while command != "":
command = input('>>> ')
if command in {'n', 'e', 's', 'w', 'north', 'south', 'east', 'west', 'go north', 'go south', 'go east', 'go west'}:
travel(self, command)
elif command == 'look':
print(self.room.description)
print('Exits', self.room.exits.keys())
elif command == '':
print('You have to say what it is you want to do! Unfortunately due to a bug you must now restart the game. We are working on fixing this as soon as possible. Sorry!')
elif command == 'search':
print(self.room.roominv)
elif command == 'Take Items':
addToInventory(self.room.roominv)
elif command == 'Inventory':
print(self.bag)
else:
print('Invalid command')
player = Player("Jeff", 100, [], 'introd', command)
也欢迎大家批评我的代码!我正在努力学习,任何来自更有经验的人的 advice/comments 都会很棒。
你的addInventory
方法是错误的。首先,您必须使用实例变量 self.room
而不是 class Room
本身。其次,如果你想要清理整个 roominv
字典,你应该尝试:
def addToInventory(item):
self.bag.append(item)
self.room.roominv.clear() # this will clear the roominv dictionary
更新
如果你想从 roominv 中删除单个元素,你可以这样做:
self.room.roominv.pop(key, None)
如果键不在字典中,None
将防止 pop 引发 KeyError
little_birdie 说得对,您正在尝试访问 class room
的属性,而不是获取 Room
.[= 的实例之一20=]
此外你的 roominv
是 dict
。只有 list
获得了方法 remove()
。
要从字典中删除键,请使用:
del dict_name[key]
我刚看到,您不仅要挑选单个商品,而且要一次性挑选所有商品。 因此你可以使用:
self.room.roominv.clear()
Here is a little example 这可能会帮助您完成工作。
您可能想要做的是这样的事情:
def addToInventory(item):
self.bag.append(item)
del self.room.roominv.clear()
虽然不是代码审查,但我也会添加一些提示来修复您的其他错误,但首先,手头的问题:
Room.roominv.remove(item)
Room
是一个 class,不是一个对象,所以你不能请求它的 roominv
相反,您需要 self.room.roominv
,但是这不会起作用,因为 .remove
不是 dict
的成员,我建议进行以下更改:
您的 'Take Items'
命令应该是:
elif command.split()[0] == 'Take':
for key in list(self.room.roominv.keys()):
if self.room.roominv[key].name == command.split()[1]:
addToInventory(key)
这将允许用户只拿取可用的特定物品,并允许用户指定他们想要取走的物品。
然后你的addToInventory
函数可以是:
def addToInventory(self,key):
self.bag.append(self.room.roominv[key])
del self.room.roominv[key]
如果房间中有多个项目,这将只删除给定的项目。
del
关键字从字典中删除给定的 key/item 对。
关于你的其他问题,你的错误在这里:
elif command == '':
print('You have to say what it is you want to do! Unfortunately due to a bug you must now restart the game. We are working on fixing this as soon as possible. Sorry!')
只需更改 command
的内容即可修复:
elif command == '':
print('You have to say what it is you want to do!')
command = '#'
为了解决您需要多次输入指令的问题,我建议您执行以下操作:
从您的代码顶部删除 command = input('>>> ')
。
将 while command != ""
循环上方的 command = input('>>> ')
替换为 command = ' '
并更新您的 Player
以不使用 move
(这意味着编辑 __init__
函数以及在 player
底部的初始创建您的代码:player = Player("Jeff", 100, [], 'introd')
)
最后,吹毛求疵,为什么不把你的 while
循环放在一个函数中呢?,所有这些导致:
class Player:
def __init__(self, name, health, bag, room_name):
self.name = name
self.health = health
self.bag = bag
self.room = world[room_name]
def travel(self, direction):
if direction not in self.room.exits.keys():
print("You can't go that way!")
else:
new_room_name = self.room.exits[direction]
print("moving to", new_room_name)
self.room = world[new_room_name]
print(self.room.description)
print(self.room.actions)
def addToInventory(self, key):
self.bag.append(self.room.roominv[key])
del self.room.roominv[key]
def play(self):
command = " "
while command != "":
command = input('>>> ')
if command in {'n', 'e', 's', 'w', 'north', 'south', 'east', 'west', 'go north', 'go south', 'go east', 'go west'}:
self.travel(command)
elif command == 'look':
print(self.room.description)
print('Exits', self.room.exits.keys())
elif command == '':
print('You have to say what it is you want to do!')
command = '#'
elif command == 'search':
print(self.room.roominv)
elif command.split()[0] == 'Take':
itemTaken = False
for key in list(self.room.roominv.keys()):
if self.room.roominv[key].name == command.split()[1]:
self.addToInventory(key)
itemTaken = True
if not itemTaken:
print("I can't find that")
elif command == 'Inventory':
print(self.bag)
else:
print('Invalid command')
player = Player("Jeff", 100, [], 'introd')
player.play()
这些更改会导致需要进行一些其他更改,例如在查看您的库存时,打印出每个项目的 .name
,而不是对象本身。
还可以通过完整的代码审查进行更多更改,但是为此您应该 post 在 Code Review 上编写代码,请注意,代码审查只能用于 完整的工作代码,所以在post进入之前确保其中没有任何破坏游戏的错误。
一个例子运行:
>>> n
moving to clearing
You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
{'Go East', 'Take flower', 'Go south'}
>>> s
moving to introd
You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
{'Search the ground', 'Go North'}
>>> n
moving to clearing
You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
{'Go East', 'Take flower', 'Go south'}
>>> s
moving to introd
You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
{'Search the ground', 'Go North'}
>>> search
{'sword': <__main__.Weapon object at 0x00000000040B9470>}
>>> Take sword
I can't find that
>>> Take Sword
>>> Inventory
[<__main__.Weapon object at 0x00000000040B9470>]
>>> search
{}
>>>