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

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

二、項(xiàng)目的設(shè)計(jì)模式
2.2 單例模式
確保一個(gè)類(lèi)只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)點(diǎn)來(lái)訪問(wèn)這個(gè)唯一實(shí)例。
----《設(shè)計(jì)模式》 GoF
? 即一個(gè)類(lèi)只能創(chuàng)建一個(gè)實(shí)例,并且這個(gè)實(shí)例必須得由類(lèi)本身提供。
? 表現(xiàn)在c++里,便是其構(gòu)造函數(shù)是私有的、外界無(wú)法訪問(wèn);同時(shí),提供一個(gè)公有Instance()方法來(lái)返回一個(gè)實(shí)例,且這個(gè)實(shí)例是全局唯一的。
2.2.1 結(jié)構(gòu)
??

2.2.1 例子
??我們以“Bob的一天”這個(gè)項(xiàng)目為例,在狀態(tài)模式下,我們?yōu)锽ob這個(gè)實(shí)例對(duì)象分配了四個(gè)狀態(tài)類(lèi),且這四個(gè)類(lèi)繼承了State類(lèi),同時(shí)他們的數(shù)據(jù)是共享的。
? 假如我們沒(méi)有使用單例模式來(lái)設(shè)計(jì)狀態(tài)類(lèi),那么在游戲的開(kāi)發(fā)過(guò)程中,可能會(huì)發(fā)生開(kāi)發(fā)人員不小心在一個(gè)狀態(tài)過(guò)程中實(shí)例化了多個(gè)對(duì)象,造成內(nèi)存浪費(fèi),甚至是數(shù)據(jù)錯(cuò)亂等情況(由于Bob的數(shù)據(jù)是共享的)。
? 因此,每個(gè)具體的狀態(tài)被簡(jiǎn)化為一個(gè)Singleton對(duì)象,在這種情況下是十分有效的。


? 與書(shū)中提供的代碼不同的是,筆者將書(shū)中的單例模式改為Meyers' Singleton,用到了C++11標(biāo)準(zhǔn)中的Magic Static特性,來(lái)自《Effective C++》。
如果當(dāng)變量在初始化的時(shí),并發(fā)同時(shí)進(jìn)入聲明語(yǔ)句,并發(fā)線程將會(huì)阻塞等待初始化結(jié)束。
----《Effective C++》 Meyers
??這是最為推薦的一種單例模式實(shí)現(xiàn)方式,保證了線程安全,代碼也足夠簡(jiǎn)潔:
通過(guò)局部靜態(tài)變量的特性保證了線程安全 (C++11, GCC > 4.3, VS2015支持該特性);
不需要使用共享指針,代碼簡(jiǎn)潔;
注意在使用的時(shí)候需要聲明單例的引用?
Single&
?才能獲取對(duì)象。

參考:?
《游戲人工智能編程案例精粹》
《設(shè)計(jì)模式》 GoF?
《Effective C++》 Meyers
? c++單例模式總結(jié)與剖析,? 行者孫,https://www.cnblogs.com/sunchaothu/p/10389842.html?? ?
相關(guān)代碼下載:https://github.com/linpeijie/GameToy/tree/master/GameAI/FSM