我有一个很大的游戏对象列表 (30-50),它们按照 sudo 顺序在 5-7 种状态之间变化,从而从根本上改变了它们的行为。
我最初的天真的方法是给每个游戏对象一个状态变量,然后每个 Action 命令都会通过 if-else block 来找到与状态相对应的正确 Action 。
选项 1(朴素方法)
class Bot:
def action(self):
if self.state == 1:
action1()
if condition1_to_2():
self.state = 2
elif self.state == 2:
action2()
#...
list_of_bots = [Bot(), Bot(), ...]
for bot in list_of_bots:
bot.action()
但我想,有 50 个游戏对象,这种 if-else 遍历不会开始占用大量时间吗?
我不能通过直接声明正确的代码来加快性能吗?
我能想到实现这一点的唯一方法是使用继承(接口(interface)或子类)并使每个游戏对象的每个游戏状态成为自己的子类,每次更改状态时都会销毁并创建一个新对象。
选项 2(继承)
class Bot:
def action(): raise NotImplementedError
class Bot1(Bot):
def action():
action1()
class Bot2(Bot):
def action():
action2()
#...
list_of_bots = [Bot1(), Bot2(), ...]
for bot in list_of_bots:
bot.action()
这样每个游戏对象就不必在游戏的每个周期中检查它的状态,从而每个周期节省 300 次操作。
我唯一的问题是,制作这么多新类(class)感觉有点矫枉过正。是否有更紧凑但同样有效的解决方案来解决这个问题?
我想到了状态字典或列表(假设它们提供 O(1) 访问时间),但是如何将列表链接到代码块?
选项 3(不可能?)
class Bot:
def __init__(self):
self.action_list = [action1(), action2(), ...]
self.state = 1
def action():
self.action_list[self.state]
该解决方案必须在原始 python3 中完成(无需 pip 安装)。
最佳答案
您的选项 3 可以使用函数引用,但是我不确定这个程序结构是否最好使用。但要完成存储函数引用列表,您可以这样做:
class Bot:
def __init__(self, game_map):
self.action_list = [self.action1, self.action2] # Stores function references
self.state = 1
self.game_map = game_map # Pass in game_map object that the class can use
def action(self):
self.action_list[self.state]() # Calls function reference
def action1(self):
# Does something
def action2(self):
# Does something
编辑:我添加了一个示例,说明如何传递您在评论中提到的 game_map
对象。然后,您可以在操作函数中的任何位置使用 self.game_map
,只要您每次修改该 map 而不是创建新 map ,这将是您的游戏 Controller 正在更新的同一对象。
关于python - 调用对象的状态特定代码块的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53013141/