调用对象状态特定的代码块的最有效方法是什么?

时间:2018-10-26 16:45:35

标签: python python-3.x performance

我有一大堆(30-50个)游戏对象,它们以5个国家/地区的状态在sudo-sequence顺序中发生变化,从而从根本上改变了他们的行为。

我最初的幼稚方法是为每个游戏对象分配一个State变量,然后每个动作命令将其通过if-else块,以找到与state对应的正确动作。

选项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个游戏对象,这种遍历难道就不会占用大量时间吗?

我不能直接使用状态正确的代码来提高性能吗?

我能想到的唯一方法是使用继承(接口或子类),并使每个游戏对象的每个游戏状态成为其自己的子类,并在每次状态改变时销毁并创建一个新对象。

选项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次操作。

我唯一的问题是制作这么多新课程有点过头了。是否有更紧凑但同样有效的解决方案?

我以为状态字典或列表(假设这些字典或列表具有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)。

1 个答案:

答案 0 :(得分:0)

您的选项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,只要您每次修改该地图而不是创建一个新地图,它就将成为您的游戏控制器正在更新的同一对象。