当前位置: 首页 > 知识库问答 >
问题:

Python 3:如何在基于文本的游戏中从库存中删除项目?

钱承允
2023-03-14

我一直在做一个类似Zork的基于文本的冒险游戏,作为一个个人项目来自学python。一般来说,我对编码是新手,所以我对基本原理不太清楚。

在我的游戏中,我已经达到了可以成功导航我创建的地图,并可以自由添加新房间/物品的地步。我目前正在努力使“库存”系统正常工作。

目前,我的Room类中有一本名为“roominv”的字典,它作为每个特定房间的目录。我在player类中还有一个名为“bag”的字典,它用作player目录。

目前,游戏是有缺陷的,未完成的,所以要拿起一件物品,你必须拿起你房间里的所有物品,但这不是我遇到的问题。

我不知道如何清空roominv字典,一旦玩家拿起房间里的物品。现在我可以将物品添加到玩家包中,但它会创建一个副本,而不会将它们从roominv中删除。

我已经尝试过使用del、delattr和pop,但要么我没有正确地使用它们(这是我的假设),要么这不是正确的方法。我也试过了。删除我在下面代码中留下的内容。它返回此错误消息

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次(Bug),然后你可以使用这些钥匙四处走动,或者在房间里拿起带有“拿走物品”的物品。

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)

也可以随意批评我的代码!我正在努力学习,任何来自更有经验的人的建议/评论都会很棒。

共有3个答案

谯英彦
2023-03-14

您的addInventory方法是错误的。首先,您必须使用实例变量self.room而不是类Room本身。其次,如果你想要清理整个room inv字典,你应该尝试:

def addToInventory(item):
    self.bag.append(item)
    self.room.roominv.clear()  # this will clear the roominv dictionary

如果你想删除一个单一的元素,你可以这样做:

self.room.roominv.pop(key, None)

将防止弹出引发一个KeyError的情况下,关键是不存在的判决

柳才良
2023-03-14

little_birdie说得对,你试图访问类room的一个属性,而不是获取room的一个实例

此外,您的房间inv是一个判决。只有list得到了方法删除()。若要删除一个密钥,请使用:

del dict_name[key]

我刚才看到,你不想只挑选一个项目,而是一次挑选所有项目。因此,您可以使用:

self.room.roominv.clear()

这里有一个小例子可以帮助你完成你的工作。

你可能想做的事情是这样的:

def addToInventory(item):
    self.bag.append(item)
    del self.room.roominv.clear()
刘意
2023-03-14

虽然不是代码审查,但我将添加一些指针来修复您的其他bug,但首先是手头的问题:

Room.roominv.remove(item)

Room是一个类,而不是一个对象,因此您不能要求提供它的roominv,而是需要self。房间roominv,但它不能像那样工作。remove不是dict的成员,我建议进行以下更改:

您的命令应该是:

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关键字从字典中删除给定的键/项对。

与您的其他问题相关,您的错误如下:

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 == '':
    print('You have to say what it is you want to do!')
    command = '#'

要解决多次输入指令的问题,我建议您执行以下操作:

删除命令=输入('

替换命令=输入('

并更新您的Player以不移动move(这将意味着编辑\uuuu init\uuuuu函数以及在代码底部初始创建PlayerPlayer=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()

这些更改将导致需要一些其他更改,如查看库存时,打印。每个项目的名称,而不是对象本身。

通过完整的代码审查还可以进行更多的更改,但是您应该在代码审查中发布您的代码,请注意,代码审查应该只用于完整的工作代码,所以在发布之前确保其中没有任何破坏游戏规则的错误。

运行示例:

>>> 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
{}
>>> 

 类似资料:
  • 在我的大学课程中,我们必须创建一个基于文本的游戏,在这个游戏中,你可以进出房间收集物品。我仍在尝试掌握python和一般编码的诀窍,因此我一直在努力完成这个项目。在大多数情况下,我的代码可以正常工作,但我可以多次添加一个项目。如何将其添加到库存中,然后从文件室中删除,以防止用户多次添加?

  • 我正在Java制作一个基于文本的冒险游戏。我需要让用户能够拿起物品并将其放入库存中,但我不确定如何做到! 这是我的项目当前的设置方式: 我需要能够在某些房间里有特定的物品。有人有什么建议吗?

  • 我试着查看玩家的物品清单中是否有物品,如果有,就移除其中一个。以下是我现在所拥有的: 它获取他们是否拥有该项目,但不会删除一个。 如何从玩家的库存中移除一件物品?

  • 所以我是Java编码的新手,我对C#有很好的经验,我知道它们非常相似。我目前正在通过创建一个文本冒险游戏来处理Java,游戏使用案例(案例1、案例2、默认等),目前我正在开发一个保存和加载功能,但我不知道如何保存一个使用案例来进一步编码的分支游戏,有人有什么想法吗?

  • 我是javafx新手,正在尝试在textflow中显示大量文本。它显示得很好,但我就是不知道如何删除文本。 所以我要做的是像这样从textFlow中删除所有文本节点 但当我这样做并向textFlow添加一些内容时,它会显示在已经显示的文本之后。我想删除那里的文本,并显示从文本流开始添加的文本。 我想我必须以某种方式重新呈现textflow的视图,但我不知道怎么做。那么如何删除所有内容并重新添加文本

  • 问题内容: 我正在扩展BaseAdapter以创建自定义listview行。我有上下文菜单,每当用户按住该行时就会打开,并提示他是否要删除它。但是,如何删除行?哈希图仅是测试数据。 问题答案: 您不要从适配器中删除!您从项目中删除!适配器位于您的商品和视图之间。您可以从视图中获得职位,并根据职位可以删除项目。然后,适配器将刷新您的视图。 那意味着你需要做这样的事情