本文內容包含如下章節:html
Chapter 2 AI Methods算法
Chapter 2.1 General Notes編程
本書英文版: Artificial Intelligence and Games - A Springer Textbook網絡
這個章節主要討論了在遊戲中常常用到的一些基礎的人工智能算法。這些算法大部分都出如今一些人工智能和機器學習的入門書籍中。在講解算法在遊戲中的應用的時候,會以吃豆人(Ms Pac-Man)做爲樣例,講解怎麼用行爲樹算法,樹搜索算法,監督學習算法,無監督學習算法,強化學習算法和進化算法來構建一個玩遊戲的AI。數據結構
吃豆人app
一. AI算法的基本要素框架
這些AI算法雖然形態各有不一樣,可是本質上都是基於兩個基本的要素來作文章。一個是算法的表示(Representation), 另一個是效用(Utility)。dom
首先是怎麼把學到的玩遊戲的知識用某種數據結構來表示出來。這個數據結構也是和要用的算法強相關的。好比若是用文法演化算法(Grammatical Evolution),最後學到的就是一些文法(Grammars);若是用機率模型或者有限狀態機,最後知識就表示成一個圖(Graphs);而行爲樹和決策樹還有遺傳算法會學到一顆樹(Trees),神經網絡天然是聯結主義的(Connectionism), 遺傳算法和演化策略會帶來一些基因編碼(Genetic Representation), 而TD-learning 和 Q-learning則學到了一下狀態轉移的表格(Tabular)。機器學習
固然,尋找一個最優的算法表示一般是很難的,而且世界上沒有免費的午飯,算法之間老是各有利弊的。不過通常來講,咱們但願選擇的算法的表示儘量的簡單,和佔用更小的空間。而咱們須要有一些先驗知識來找到一個較好的算法表示。模塊化
另一方面,咱們會用效用(Utility)這個來自博弈論的術語來指導算法的訓練。不嚴格的來講,能夠把它看作一個函數,輸入是當前狀態和算法可能的動做(Action),輸出是算法作出某個動做所可以得到的好處。理論上來講,若是咱們能獲得一個準備的Utility Function, 咱們的算法每次均可以找到最優的路徑。但實際上,咱們只可以獲得一個估計值,或者更確切的,在沒有先驗知識的狀況下,咱們只能經過記住咱們探索過的狀態和路徑及其得到的回報來估算一個效用值來表示某個走法的好壞(Measure of Goodness)。若是遊戲自己的狀態空間比較小,咱們能夠經過遍歷全部的可能狀況來獲得一個準備的Utility Function。而一般咱們面對的問題都有着極大的搜索空間,所以咱們但願可以儘量的探索到更多的路徑,而後在探索到的數據上進行採樣來獲得一個估計的Utility。
Utility 在不一樣的算法上的叫法會有所不一樣,在含義上也有細微的差異。例如在一些樹搜索算法上,咱們會用啓發式的規則(Heuristic)來指導算法的收斂。而在遺傳算法上,它又被叫作適應度函數(Fitting Function)。在優化算法上,咱們更經常使用的詞語是Loss, Error, Cost; 而在強化學習,Reward是一個更經常使用的單詞,這裏最主要的緣由是:作RL的人因爲成天面對着逆天難的問題,因此喜歡用reward(相對於loss)來激勵本身。(大霧)
這樣,咱們訓練AI的過程就是尋找一套Representation最好的參數,能夠最大化Utility。所以,可以學到一個好用的模型,取決於Utility Function是否設計的合理,和咱們的目標是否徹底一致。對於監督學習來講,Utility等價於其Label;對於強化學習來講,Utility來自於環境的反饋。而無監督學習的Utility則來自於數據自己的結構和共性。
二. 基於有限狀態機的AI實現
實現一個NPC,最簡單的方法當時就是寫一些規則,但這樣子顯然比較low,不過在不少場景下其實也能知足須要了。若是咱們把規則(If, else 語句)抽象,就變成了有限狀態機(Finite State Machine, FSM) 或者 行爲樹(Behavior Trees, BT)。
FSM直到21世紀的前十年都仍是普遍的應用到各類遊戲之中。咱們能夠把FSM理解爲一個圖(Graphs), 遊戲中的狀態是圖的一個節點(Nodes), 能夠相互轉化的狀態之間有連線(Edges),連線之間定義了狀態轉移(Transitions)的條件,而在每一個狀態中,定義了一系列的動做(Actions),當AI處於該狀態時,就執行具體的動做,如向左或向右或者更復雜的組合動做。
例如上面的一個基於FSM的吃豆人AI,首先定義了狀態和狀態轉移的條件。當在尋找豆子的狀態的時候,能夠給AI編程具體在每一個狀態的行爲。好比在尋找豆子的狀態,一開始隨機遊走,若是看到豆子就去吃掉它,若是看到Ghost,就進入到躲避Ghost的狀態。下面是一個簡單的3種狀態下動做的僞代碼:
def seek_pellet: while 1: if ghost_in_sight: return evade_ghost_state if power_pill_eaten: return chase_ghost_state if pellet_in_sight: go_and_eat_pellet() #using pathfinding algorithm find best action else: move_randomly()def evade_ghost: while 1: if not ghost_in_sight: return seek_pellet_state if power_pill_eaten: return chase_ghost_state leave_the_ghost() # using tree search to find best actiondef chase_ghost: while 1: if power_pill_expired: return seek_pellet_state find_the_ghost() # using tree search to find best action
三. 基於行爲樹的AI實現
能夠看到FSM的AI的模式是很是固定的,玩家很容易發現其中的pattern,這個經過模糊邏輯(Fuzzy Logic)和增長几率能夠獲得必定緩解。另外,對於一些要完成比較難的任務的NPC,須要爲其設計不少不一樣的狀態和狀態轉移方式,整個過程是很是複雜和難以調試的。所以人們定義了行爲樹(BT),經過模塊化(Modularity)的設計,能夠把複雜的行爲拆解成簡單的任務,從而減輕整個系統的複雜度和提升可維護性。所以,自光暈2(Halo 2)以後,BT就取代了FSM,成爲遊戲工業界最經常使用的NPC算法。
行爲樹是把FSM的圖轉變成爲一顆樹結構。所以行爲樹是有一個Root節點,而後往下有一些中間節點,最後是葉子節點。咱們從根節點遍歷行爲樹,每個子節點被執行的時候都按預設的時間間隔回傳三種信息給到父節點:
Run: 表示這個節點還在繼續執行
Success:表示這個節點已經成功執行了
Failure: 表示這個節點執行失敗了
而行爲樹的節點有3種類型:
Sequence: (如上圖的藍色方塊)表示該父節點會順序執行它的子節點,而且知道它的全部子節點都成功執行了,它纔會回傳Success給更上層的節點。
Selector:(如上圖的紅色方塊)表示該父節點會從其子節點中選擇其中一個執行,只要有一個子節點執行成功,該父節點就會返回Success。除非全部子節點都執行失敗,該父節點纔會返回失敗。父節點選擇子節點的順序有兩種方式:a. Probability:按機率選取子節點執行的順序;b. Priority: 該預設的順序選取子節點。
Decorator:(如上圖紫色的方塊)至關於節點執行增長一些條件,好比限定執行的時間,或者失敗從新執行的次數。如圖中是限定了一個條件,只有在看到Ghost的時候,吃豆子(Eat Next Pellet)這個節點纔會返回Fail 狀態。
能夠看到,行爲樹的結構能夠比較方便的把複雜的行爲分解成層次的簡單結構,方便維護。例如我能夠在吃豆子(Eat Next Pellet)這個Node上設定新的很複雜的算法,但不會影響整個樹的其餘節點。同時測試起來也比較方便,咱們能夠針對行爲樹的某個子樹來進行測試,而不影響整個大的框架。
固然,行爲樹和FSM也有一樣的問題,就是NPC的行爲的可預見性仍是比較大的,整個行爲的模式仍是受限於總體的行爲樹框架。雖然能夠經過一些機率的方式來增長一些隨機性,但總體來看仍是有不少侷限性的。
在行爲樹裏面,選擇不一樣子樹的方式仍是稍顯簡單,經過必定的規則,或者預設的機率來選擇不一樣的子節點(子樹)來執行。所以人們在上面添加了基於效用的方式(Utility-based)。簡單說來,咱們定義一個Utility Function: u = F(S,a)。 根據當前遊戲的環境狀態S, 獲得某一個行爲a的效用值u。這個Utility Function是能夠經過規則設定,也能夠經過一些複雜的學習方法來獲得。好比咱們能夠用一個神經網絡去預測在當前狀態下,作哪一個動做更好。好比在吃豆人遊戲中,可能咱們就不須要來寫一些規則來判斷該作什麼動做(好比看到Ghost就中止吃豆子的子樹執行),而能夠用更動態的方式來控制(好比Ghost在多遠的地方,往哪一個方向走,豆子和Ghost和NPC的位置關係怎麼樣)是否中止吃豆子的子樹執行。固然更General的說,其實後續的強化學習,監督學習也好,都是在學一個Utility Function來控制NPC的動做。本質上,Utility-based AI是一種構建NPC的思想,能夠應用到不一樣的AI方法上。
更多推薦
「深度兼容測試」現已對外,騰訊專家爲您定製自動化測試腳本,覆蓋應用核心場景,對上百款主流機型進行適配兼容測試,提供詳細測試報告。
點擊:https://wetest.qq.com/cloud/deepcompatibilitytesting 瞭解更多詳情。
若是使用當中有任何疑問,歡迎聯繫騰訊WeTest企業QQ:2852350015