本文发表于恋花蝶的博客
http://blog.csdn.net/lanphaday,欢迎转载,但必须保留文章内容完整且包含本声明。违者必究。
[python]有限状态机(FSM)简单实现
简述
有限状态机(以下用FSM指代)是一种算法思想,简单而言,有限状态机由一组状态、一个初始状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成。在Gof的23种设计模式里的state模式是一种面向对象的状态机思想,可以适应非常复杂的状态管理。
现在,FSM被普遍用于搜索引擎的分词、编译器实现和我们普遍关注的游戏开发中。游戏开发中,通常用FSM实现NPC控制,如当NPC受到攻击时根据健康、力量等选择逃跑还是反攻的行为,一般是用FSM实现的。FSM的实现方法有很多种,不能简单地说孰优孰劣,但现代开发中,一般都比较推荐面向对象的实现方式:因为可重用性和健壮性更高,而且当需求变更的时候,也有很好的适应性。
实践
理论从实践中来,也要回到实践中去。我们现在通过实例来探索一下FSM的实现吧。首先假设有这样一个世界(World),世界里只有一台永不缺乏动力的汽车(Car),汽车是次世代的,没有油门方向盘之类的落后设备,只有两个互斥的按钮——停止(Stop)和行进(Run),随着时间的流逝,汽车根据驾驶员的操作走走停停。下面的代码可以实现这种功能:
while True:
key = get_key() # 按下什么键
if key == "stop":
stop(car)
elif key == "run":
go(car)
keep(car) # 保持原态
|
完成了功能而且直观、简洁的程序员万岁!但这时候客户(策划或者玩家)觉得走走停停太没意思了,他们想要掉头、左转和右转的功能,我们就要在while循环里增加更多的if...else分支;他们想要更多的车,我们就要要在每一个分枝里增加循环;他们不仅仅想要Car了,他们还要要玩Truck,这时我们就需要在分枝的循环里判断当前的车是否支持这个操作(如Truck的装卸货物Car就不支持);他们……
这个while循环终于无限地庞大起来,我们认识到这样的设计的确是有点问题的,所以我们尝试用另一种方法去实现FSM。首先我们来实现汽车(Car):
class Car(object):
def stop(self):
print "Stop!!!"
def go(self):
print "Goooooo!!!"
|
只有两个方法stop和go,分别执行Stop和Run两个按钮功能。接下来我们编写两个状态管理的类,用以处理当按钮被按下、弹起和保持时需要工作的流程: