基礎(chǔ) | 簡單的智能體----有限狀態(tài)機(jī)(一)

本系列為筆者初學(xué)c/c++和游戲AI開發(fā)的學(xué)習(xí)經(jīng)歷,練習(xí)為主,不涉及到具體的游戲開發(fā)軟件學(xué)習(xí)(如unity,虛幻4等),適合剛?cè)腴T的小伙伴一起學(xué)習(xí)探討,歡迎在評論區(qū)留下意見。
開發(fā)語言:c/c++ (11及以上)
開發(fā)平臺(tái):macOS mojave / Linux
編譯器:vs Code / g++

介紹
? 有限狀態(tài)機(jī)(finite-state machine,F(xiàn)SM)是表示有限個(gè)狀態(tài)在以及在這些狀態(tài)之間的轉(zhuǎn)移和動(dòng)作等行為的數(shù)學(xué)模型。圖靈機(jī)也是一種有限狀態(tài)機(jī)。
? 好在于,對游戲開發(fā)人員來說,不需要過分糾結(jié)于數(shù)學(xué)上的嚴(yán)格定義,我們只需要掌握這樣一個(gè)概念即可:有限狀態(tài)機(jī),是指把一個(gè)對象的行為分解成易于處理的“塊”或狀態(tài)。
??簡單的如家里墻上控制燈的開關(guān),它有兩種狀態(tài):開或關(guān)。兩種狀態(tài)之間的轉(zhuǎn)換通過我們的手指的輸入產(chǎn)生。

??稍微復(fù)雜的可以用一個(gè)狀態(tài)轉(zhuǎn)換表來描述,其中每個(gè)狀態(tài)可視為一個(gè)分離的對象:

? 上圖中,當(dāng)一只史萊姆接受到刺激(即遇到某個(gè)條件),會(huì)發(fā)生狀態(tài)轉(zhuǎn)換,從一種狀態(tài)變成另外一種狀態(tài)。比如一只被攻擊的史萊姆在逃跑時(shí)(狀態(tài)1),發(fā)現(xiàn)玩家沒有繼續(xù)攻擊(條件-->安全),會(huì)停止逃跑開始在領(lǐng)地里巡邏(狀態(tài)2)。
? 盡管如今游戲AI領(lǐng)域有更專業(yè)更復(fù)雜的智能體結(jié)構(gòu),但熟練掌握FSM對我們理解更復(fù)雜的模型有很大幫助,且FSM在游戲開發(fā)領(lǐng)域仍有很大作用,原因在于它有幾大優(yōu)點(diǎn):
編程快速簡單:從最簡單的 if-then 形式,到單例模式,每種編程語言都能夠快速實(shí)現(xiàn)一個(gè)FSM。
易于調(diào)試:每個(gè)狀態(tài)單獨(dú)分離出來作為“塊”來管理,這樣當(dāng)哪里出現(xiàn)問題時(shí),可以快速定位出錯(cuò)的位置,也可以快速修改。
較少的計(jì)算開銷:有限狀態(tài)機(jī)屬于“硬編碼”范疇,本質(zhì)上是 if-this-then-that 類型,規(guī)則已經(jīng)事先寫好,不需要額外的計(jì)算。
基于直覺:我們總能很自然的聯(lián)想到我們自己總是處于一系列的狀態(tài)中,并且習(xí)慣性的把狀態(tài)的轉(zhuǎn)換歸結(jié)為一個(gè)又一個(gè)“選擇”。選擇使我們改變當(dāng)前狀態(tài),進(jìn)入另一種狀態(tài)。
靈活性:在游戲開發(fā)中,開發(fā)人員可以根據(jù)需求靈活的調(diào)整FSM的結(jié)構(gòu),增加或刪除某些狀態(tài)。
? 當(dāng)然,現(xiàn)實(shí)中的事物并非如此簡單的處在某一種獨(dú)立的狀態(tài)中,但是作為入門學(xué)習(xí),不用去思考這么多。同時(shí),我們也需要認(rèn)識(shí)到,有限狀態(tài)機(jī)的局限性:
區(qū)分“動(dòng)作”和“狀態(tài)”:狀態(tài)描述了一個(gè)對象一種穩(wěn)定而持續(xù)的行為,如果沒有外部“條件”的輸入,則該狀態(tài)不會(huì)改變;動(dòng)作則是不穩(wěn)定的,一旦執(zhí)行完畢就會(huì)自動(dòng)結(jié)束,不會(huì)長時(shí)間存在。
狀態(tài)和狀態(tài)之間是相互獨(dú)立的,這對構(gòu)建更真實(shí)的智能體是極大的阻礙。

參考:
《游戲人工智能編程案例精粹》
?維基百科
相關(guān)代碼下載:https://github.com/linpeijie/GameToy/tree/master/GameAI/FSM