【问题标题】:A more efficient way to use/gather data in a text-based game在基于文本的游戏中使用/收集数据的更有效方式
【发布时间】:2015-10-29 18:52:11
【问题描述】:

我已经开始开发一款基于文本的冒险游戏。该环境的行为类似于 Sierra 游戏,但没有图形界面,所有命令都是文本。

目前,游戏中的任何对象(例如角色、房间、物品等)都由字典定义。键是数据值的名称(名称、描述等),如下所示:

flash_light={
'name':'Flashlight',
'desc':'A flashlight, probably belonging to an eningeer on the ship.',
'consumable':False
}

玩家的物品栏和全局物品栏是字典,其中键是用来调用物品的“代号”字符串,物品是引用它的字典。 比如说,如果你想拿一个你在房间里找到的物品,房间的字典有一个属性,可以将房间的库存作为一个列表来跟踪。此列表包含作为其中项目“代号”的字符串。

my_room={
'name':'My Room',
'codename':'my_room',
'desc':'A hot, stuffy room shared with 3 other passengers. My trunk is   here.\
The door is on the NORTH wall.',
'access':True,
'direc':{'north':'st_hall_1'},
'inven':['flashlight']
}

在命令确定你要求拿的物品实际上在房间里之后,它会运行:

current_pos.inven().remove(target)
player_inv.update({target:global_inv[target]})

这些行从房间的物品栏列表中删除字符串,然后将键和项目添加到玩家的物品栏字典中。键是您尝试获取的对象的字符串名称,该项目在字符串名称处定义为 GLOBAL 库存中的字典。

我有这么多关于该程序的调用的原因是,当我将字典引用到其他字典时,我一直遇到问题(即,一个房间有一个它连接到的房间的列表),而这些字典可能没有定义然而。我尽可能保持函数的通用性,并使用 string-to-call-a-dict 来避免给出未定义的名称作为参数。

我的主要问题是:如果可能,我怎样才能提高效率? 或者,我构建系统的方式,是否需要进行重大重组才能改进?

【问题讨论】:

  • 我唯一的建议是将你的对象和房间变成类,这样你就可以将代码直接更新到对象。

标签: python dictionary game-engine text-based


【解决方案1】:

你应该使用类而不是字典。 首先创建一个看起来像这样的通用项目类:

class Item(object):
    def __init__(self, name, codename, description, is_consumable):
        self._name = name
        self._description = description
        self._is_consumable = is_consumable

然后为每种类型的项目创建一个类:

class Flashlight(Item):
    def __init__(self, codename):
        super(Flashlight, self).__init__('Flashlight', codename,
            'A flashlight, probably belonging to an eningeer on the ship', False)

考虑为消耗品创建一个单独的项目,该项目具有处理该项目消耗的consume() 方法。

创建一个类似这样的 Room 类:

class Room(object):
    def __init__(self, name, codename, description, access, directions, inventory):
        self._name = name
        self._codename = codename
        self._description = description
        self._access = access
        self._directions = directions.copy()
        self._inventory = inventory[:]

我在 self._directions 的定义中使用 copy 和在 self._inventory 的定义中使用 [:] 来创建每个对象的副本,而不是使用原始对象。

为您想要的每个房间实例化它。

my_room = Room('My Room', 'my_room', 
'A hot, stuffy room shared with 3 other passengers. My trunk is here. The door is on the NORTH wall.',
True, {'north': 'st_hall_1'}, [Flashlight('flashlight')])

然后你可以添加一些方法,让玩家可以在房间内做游戏允许他们做的任何事情。 您还应该创建一个 Character 类、一个 Player 类等等。

因此,类是提高游戏效率的关键。每个类都应该包含自己的东西,而不是将所有游戏逻辑包含在同一个函数中(或其中几个)。

编辑:现在我看到了你的代码,你可以做一些事情来让它变得更好: 在您的“主要”中,使用仅根据命令选择正确操作的函数字典,而不是一长串 if 语句(另外,您没有使用 else!这意味着这些语句中的每一个在采取行动后仍会评估),如下所示:https://softwareengineering.stackexchange.com/questions/182093/why-store-a-function-inside-a-python-dictionary 您的类仅包含 getter 函数,可以使用 @property 装饰器 (How does the @property decorator work?) 进行定义

在您的房间定义中,您可以清楚地看到类如何更好:与其一遍又一遍地编写相同的字段(并希望您没有在任何地方出现拼写错误),您可以使用您已经使用的类来实例化它们定义。项目定义也是如此。 您还可以创建一个consume() 方法,该方法应用特定消耗品的任何效果,use() 用于可用物品(例如您的手电筒和螺丝刀)等。

【讨论】:

  • 这或多或少是一种更快的方法来做我所做的事情。我确实使用类,而且大多以相同的方式使用,只是当我调用 Room 时,我会根据数据字典调用它。如果我理解,您建议创建一个项目类,然后创建属于 OF TYPE 项目的类。那么对于房间,而不是引用字典的类函数,只需将房间定义为教室,它已经传递了它需要的数据?另外,我不清楚 .copy() 应该做什么。最后,你想要一个当前代码的 pastebin 吗?我只是想确保我的解释确实解释了程序。
  • 我建议你使用类的主要原因是类可以有方法来包含它们的操作逻辑。在我的示例中我没有指定任何方法,因为我不知道可以对您游戏中的一般物品或房间执行什么样的操作。但现在我想起来了,Flashlight 类中的toggle 函数可能是一个很好的例子。是的,pastebin 可以帮助我更好地了解您的游戏。
  • pastebin.com/jSyAridz 是目前的程序。另外,我感谢您的帮助。我的意思是,这就是我来的目的,但真的,谢谢。如果您需要澄清任何事情,我可以提供。
  • 好的,我在浏览完代码后编辑了我的答案。希望对您有所帮助。
  • 不过,.copy() 函数又是干什么用的?
猜你喜欢
  • 2021-08-11
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-07-08
  • 2015-09-10
相关资源
最近更新 更多