青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

什么是有限狀態機FSM

簡介

有限狀態機(以下用FSM指代)是一種算法思想,簡單而言,有限狀態機由一組狀態、一個初始狀態、輸入和根據輸入及現有狀態轉換為下一個狀態的轉換函數組成。在Gof23種設計模式里的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!!!" 

只有兩個方法stopgo,分別執行StopRun兩個按鈕功能。接下來我們編寫兩個狀態管理的類,用以處理當按鈕被按下、彈起和保持時需要工作的流程:
class stop_fsm(base_fsm):
       def enter_state(self, obj):
              print "Car%s enter stop state!"%(id(obj))
 
       def exec_state(self, obj):
              print "Car%s in stop state!"%(id(obj))
              obj.stop()
 
       def exit_state(self, obj):
              print "Car%s exit stop state!"%(id(obj)) 
class run_fsm(base_fsm):
       def enter_state(self, obj):
              print "Car%s enter run state!"%(id(obj))
 
       def exec_state(self, obj):
              print "Car%s in run state!"%(id(obj))
              obj.go()
 
       def exit_state(self, obj):
              print "Car%s exit run state!"%(id(obj)) 

stop_fsmrun_fsm都繼承自base_fsmbase_fsm是一個純虛的接口類:
class base_fsm(object):
       def enter_state(self, obj):
              raise NotImplementedError()
 
       def exec_state(self, obj):
              raise NotImplementedError()
 
       def exit_state(self, obj):
              raise NotImplementedError() 

enter_state obj進入某狀態的時候調用——通常用來做一些初始化工作;exit_state也離開某狀態的時候調用——通常做一些清理工作;而 exec_state則在每一幀的時候都會被調用,通常做一些必要的工作,如檢測自己的消息隊列并處理消息等。在stop_fsmrun_fsm兩個類 的exec_state函數中,就調用了對象的stopgo函數,讓汽車保持原有的狀態。
至現在為止,Car還沒有接觸到FSM,所以我們需要提供一個接口,可以讓它擁有一個FSM
       def attach_fsm(self, state, fsm):
              self.fsm = fsm
              self.curr_state = state 

我們還需要為Car提供一個狀態轉換函數:
       def change_state(self, new_state, new_fsm):
              self.curr_state = new_state
              self.fsm.exit_state(self)
              self.fsm = new_fsm
              self.fsm.enter_state(self)
              self.fsm.exec_state(self) 

Car提供一個保持狀態的函數:
       def keep_state(self):
              self.fsm.exec_state(self) 

現在只有兩個狀態,但我們知道需求隨時會改動,所以我們最好弄一個狀態機管理器來管理這些狀態:
class fsm_mgr(object):
       def __init__(self):
              self._fsms = {}
              self._fsms[0] = stop_fsm()
              self._fsms[1] = run_fsm()
      
       def get_fsm(self, state):
              return self._fsms[state]
      
       def frame(self, objs, state):
              for obj in objs:
                     if state == obj.curr_state:
                            obj.keep_state()
                     else:
                            obj.change_state(state, self._fsms[state]) 

fsm_mgr最重要的函數就是frame,在每一幀都被調用。在這里,frame根據對象現在的狀態和當前的輸入決定讓對象保持狀態或者改變狀態。
這時候,我們的實例基本上完成了。但我們還要做一件事,就是建立一個世界(World)來驅動狀態機:
class World(object):
       def init(self):
              self._cars = []
              self._fsm_mgr = fsm_mgr()
              self.__init_car()
 
       def __init_car(self):
              for i in xrange(1):   #
生產汽車
                     tmp = Car()
                     tmp.attach_fsm(0, self._fsm_mgr.get_fsm(0))
                     self._cars.append(tmp)
 
       def __frame(self):
              self._fsm_mgr.frame(self._cars, state_factory())
 
       def run(self):
              while True:
                     self.__frame()
                     sleep(0.5) 

從 代碼可見,World里有Car對象,fsm_mgr對象;在run函數里,每0.5s執行一次__frame函數(FPS = 2),而__frame函數只是驅動了fsm_mgr來刷新對象,新的命令是從state_factory函數里取出來的,這個函數用以模擬駕駛員的操作(按下Stop或者Run按鈕之一):
def state_factory():
       return random.randint(0, 1) 

現在我們就要初始化世界(World)可以跑起我們的FSM了!
if __name__ == "__main__":
       world = World()
       world.init()
       world.run() 

python解釋器執行上面的代碼,我們可以看到程序不停地輸出Car的狀態:
......
Car8453392 exit run state!
Car8453392 enter stop state!
Car8453392 in stop state!
Stop!!!
Car8453392 in stop state!
Stop!!!
Car8453392 exit stop state!
Car8453392 enter run state!
Car8453392 in run state!
Goooooo!!!
Car8453392 exit run state!
Car8453392 enter stop state!
Car8453392 in stop state!
Stop!!!
Car8453392 exit stop state!
Car8453392 enter run state!
Car8453392 in run state!
Goooooo!!!
Car8453392 in run state!
Goooooo!!!
Car8453392 exit run state!
Car8453392 enter stop state!
Car8453392 in stop state!
Stop!!!
Car8453392 in stop state!
Stop!!!
Car8453392 exit stop state!
Car8453392 enter run state!
Car8453392 in run state!
Goooooo!!!
...... 

 
結論
這時再回頭來看看我們之前的問題:
1
、玩家想要功能更多的Car,比如掉頭。
我 們可以通過為Car增加一個調頭(back)的方法來執行掉頭,然后從base_fsm中繼承一個back_fsm來處理調頭。之后在fsm_mgr里增 加一個back_fsm實例,及讓state_factory產生調頭指令。聽起來似乎比之前while+if的方式還要麻煩不少,其實不然,這里只有 back_fsm和為fsm_mgr增加back_fsm實例才是特有的,其它步驟兩種方法都要執行。
2
、玩家要更多的Car
這對于面向對象的FSM實現就太簡單了,我們只要把World.__init_car里的生產數量修改一下就行了,要多少有多少。
3
、玩家要更多型號的車,如Truck
Car派生一個Truck,然后增加裝貨、卸貨的接口。最大的改動在于Truck狀態轉換的時候需要一些判斷,如不能直接從裝貨狀態轉換到開動狀態,而是裝貨、停止再開動。
通 過這幾個簡單的問題分析,我們可以看到,使用面向對象的方式來設計FSM,在需求變更的時候,一般都只增刪代碼,而仍少需要改動已有代碼,程序的擴展性、適應性和健壯性都得很大的提高;因此,在世界龐大、物種煩多、狀態復雜且條件交錯的游戲開發中應用面向對象的FSM實在是明智之選。還有一點,面向對象的 FSM可以非常容易地模擬消息機制,這有利于模塊清晰化,更容易設計出正交的程序。

 

posted on 2008-12-14 18:54 肥仔 閱讀(2310) 評論(1)  編輯 收藏 引用 所屬分類: 狀態機 & 自動機 & 形式語言

評論

# re: 什么是有限狀態機FSM  回復  更多評論   

受用了
2012-07-13 14:30 | lintclr
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品少妇30p| 亚洲免费在线播放| 亚洲免费一在线| 99国产精品久久久久久久成人热 | 欧美午夜无遮挡| 国产精品高精视频免费| 国产伦精品一区| 在线观看亚洲| 亚洲久久一区二区| 午夜精品久久久久久久男人的天堂 | 美女国产精品| 亚洲国产一成人久久精品| 猛男gaygay欧美视频| 亚洲日韩欧美视频| 午夜影视日本亚洲欧洲精品| 久久国产精品第一页| 免费成人av| 国产精品看片你懂得| 国产欧美精品一区| 亚洲人体大胆视频| 午夜激情一区| 亚洲高清中文字幕| 欧美一级片在线播放| 欧美夜福利tv在线| 欧美激情综合色| 国产一区三区三区| 亚洲一级黄色| 久久―日本道色综合久久| 亚洲精品综合久久中文字幕| 亚洲国产精品国自产拍av秋霞| 亚洲激情在线| 久久精品国产99国产精品澳门 | 亚洲欧美日韩综合一区| 美女999久久久精品视频| 在线一区二区三区做爰视频网站| 欧美亚洲综合网| 国产精品九九久久久久久久| 在线成人激情视频| 久久国产精品久久精品国产| 亚洲久久成人| 欧美大片第1页| 狠狠色狠狠色综合| 欧美亚洲综合网| 日韩视频在线一区二区三区| 久久久欧美一区二区| 国内精品国语自产拍在线观看| 亚洲综合国产激情另类一区| 亚洲人成人99网站| 欧美成年视频| 亚洲激情二区| 欧美高清你懂得| 久久精品女人天堂| 国产综合18久久久久久| 欧美一区二区三区在线视频| 在线亚洲伦理| 国产精品乱码一区二区三区| 亚洲网站在线观看| 一本一本久久a久久精品牛牛影视| 欧美成人午夜视频| 亚洲区第一页| 亚洲精品乱码久久久久久按摩观 | 久久综合网hezyo| 欧美在线观看天堂一区二区三区| 国产精品视频网站| 欧美亚洲综合久久| 欧美综合国产精品久久丁香| 国产一区二区日韩精品欧美精品| 欧美一区激情| 欧美一区永久视频免费观看| 国产一二精品视频| 蜜乳av另类精品一区二区| 久久综合国产精品| 亚洲激情一区二区三区| 亚洲肉体裸体xxxx137| 欧美高清在线视频| 一二三四社区欧美黄| 一区二区三区色| 国产欧美精品在线播放| 久久久噜噜噜久久狠狠50岁| 久久久久成人网| 91久久在线观看| 一区二区三区三区在线| 国产欧美日韩精品丝袜高跟鞋| 蜜桃久久av| 久久国内精品视频| 国产亚洲精品美女| 欧美粗暴jizz性欧美20| 欧美激情在线播放| 欧美一级成年大片在线观看| 久久精品在线播放| 夜夜精品视频一区二区| 亚洲欧美在线一区二区| 亚洲福利电影| 亚洲一区二区三区乱码aⅴ| 国内久久精品视频| 亚洲三级电影在线观看 | 亚洲欧洲一区二区三区久久| 亚洲免费观看高清完整版在线观看熊 | 亚洲私人影吧| 在线免费观看一区二区三区| 亚洲毛片一区二区| 国精品一区二区三区| 亚洲精品一区二区三区不| 国产香蕉97碰碰久久人人| 亚洲精品乱码久久久久久蜜桃91 | 欧美一区二区三区视频在线 | 亚洲一区二区三区精品在线观看| 在线观看日韩精品| 亚洲综合第一页| 亚洲最新色图| 久久综合激情| 久久精品一区| 欧美视频手机在线| 亚洲国产精品久久久久久女王| 国产三级精品在线不卡| 一本久久综合亚洲鲁鲁五月天| 亚洲精品1区2区| 久久成人免费| 久久狠狠一本精品综合网| 欧美日韩在线观看一区二区| 欧美激情aⅴ一区二区三区| 国产欧美日本一区二区三区| 日韩一区二区高清| 日韩视频在线免费| 欧美成人精品一区二区三区| 免费成人高清| 尤物网精品视频| 久久婷婷人人澡人人喊人人爽| 久久精品99国产精品| 国产精品美女诱惑| 一区二区成人精品 | 国产精品v欧美精品v日韩精品| 欧美国产免费| 亚洲日韩中文字幕在线播放| 老司机成人在线视频| 性久久久久久久久久久久| 欧美日韩免费精品| 欧美黄色视屏| 亚洲三级国产| 免费日韩av| 亚洲福利视频在线| 亚洲精品视频免费| 欧美激情在线观看| 99视频精品在线| 亚洲图片你懂的| 国产精品爱久久久久久久| 中文亚洲欧美| 久久国产精品久久久久久| 国产女主播一区二区三区| 欧美呦呦网站| 欧美国产精品劲爆| 宅男噜噜噜66一区二区| 国产精品免费小视频| 欧美一级专区| 欧美高清在线播放| 在线一区亚洲| 国产日韩在线视频| 另类人畜视频在线| 亚洲另类视频| 久久国产精品一区二区| 亚洲黄色免费| 国产精品久久久久影院亚瑟| 香蕉成人久久| 欧美激情一区二区三区在线视频| 亚洲免费黄色| 国产日韩视频一区二区三区| 理论片一区二区在线| 一区二区三区四区五区精品| 久久精品综合网| 日韩亚洲欧美成人一区| 国产老肥熟一区二区三区| 久久久久久久综合狠狠综合| 亚洲精品一区在线| 久久久综合网站| 99国产精品视频免费观看一公开 | 久久精品国产清高在天天线 | 久久久噜噜噜久久久| 亚洲精品视频在线| 久久久91精品国产| 亚洲美女中出| 精品动漫3d一区二区三区| 欧美日韩精品一区二区| 久久国产视频网| 中文日韩在线视频| 亚洲高清不卡一区| 久久久国产视频91| 亚洲一级片在线看| 亚洲国产小视频| 国产亚洲精久久久久久| 欧美日韩成人综合天天影院| 欧美怡红院视频| 亚洲深夜影院| 亚洲看片免费| 亚洲国产成人不卡| 猛男gaygay欧美视频| 久久精品一二三| 欧美在线free| 香蕉久久夜色| 亚洲曰本av电影| 亚洲天堂av电影|