博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
游戏人工智能 状态驱动智能体设计——有限状态机(FSM)
阅读量:4087 次
发布时间:2019-05-25

本文共 9053 字,大约阅读时间需要 30 分钟。

状态驱动智能体设计——有限状态机(FSM)

1. 什么是有限状态机?

有限状态机,(英语:Finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。

2. 有限状态机的设计

设计者可以让角色持有一个有限状态机管理角色的不同状态,这个有限状态机也持有拥有它的角色。

有限状态机保存了当前状态、上一个状态、全局状态(全局状态总是长期存在于角色中,例如总是可以从任意状态切换到如厕状态),切换状态的方法、返回上一个状态的方法等。
每个状态都有进入、执行、退出方法,需要传进持有该状态的角色,以便状态可以达到某个状态让角色的有限状态机切换状态。

3. 核心代码展示

#ifndef STATEMACHINE_H#define STATEMACHINE_H//------------------------------------------------------------------------////  Name:   StateMachine.h////  Desc:   State machine class. Inherit from this class and create some //          states to give your agents FSM functionality////  Author: Mat Buckland 2002 (fup@ai-junkie.com)////------------------------------------------------------------------------#include 
#include
#include "State.h"template
class StateMachine{private: //a pointer to the agent that owns this instance entity_type* m_pOwner; State
* m_pCurrentState; //a record of the last state the agent was in State
* m_pPreviousState; //this is called every time the FSM is updated State
* m_pGlobalState;public: StateMachine(entity_type* owner):m_pOwner(owner), m_pCurrentState(NULL), m_pPreviousState(NULL), m_pGlobalState(NULL) {} virtual ~StateMachine(){} //use these methods to initialize the FSM void SetCurrentState(State
* s){m_pCurrentState = s;} void SetGlobalState(State
* s) {m_pGlobalState = s;} void SetPreviousState(State
* s){m_pPreviousState = s;} //call this to update the FSM void Update()const { //if a global state exists, call its execute method, else do nothing if(m_pGlobalState) m_pGlobalState->Execute(m_pOwner); //same for the current state if (m_pCurrentState) m_pCurrentState->Execute(m_pOwner); } //change to a new state void ChangeState(State
* pNewState) { assert(pNewState && "
: trying to change to NULL state"); //keep a record of the previous state m_pPreviousState = m_pCurrentState; //call the exit method of the existing state m_pCurrentState->Exit(m_pOwner); //change state to the new state m_pCurrentState = pNewState; //call the entry method of the new state m_pCurrentState->Enter(m_pOwner); } //change state back to the previous state void RevertToPreviousState() { ChangeState(m_pPreviousState); } //returns true if the current state's type is equal to the type of the //class passed as a parameter. bool isInState(const State
& st)const { return typeid(*m_pCurrentState) == typeid(st); } State
* CurrentState() const{ return m_pCurrentState;} State
* GlobalState() const{ return m_pGlobalState;} State
* PreviousState() const{ return m_pPreviousState;}};#endif
#ifndef STATE_H#define STATE_H//------------------------------------------------------------------------////  Name:   State.h////  Desc:   abstract base class to define an interface for a state////  Author: Mat Buckland 2002 (fup@ai-junkie.com)////------------------------------------------------------------------------template 
class State{public: virtual ~State(){} //this will execute when the state is entered virtual void Enter(entity_type*)=0; //this is the states normal update function virtual void Execute(entity_type*)=0; //this will execute when the state is exited. (My word, isn't //life full of surprises... ;o)) virtual void Exit(entity_type*)=0;};#endif
#ifndef MINER_OWNED_STATES_H#define MINER_OWNED_STATES_H//------------------------------------------------------------------------////  Name:   MinerOwnedStates.h////  Desc:   All the states that can be assigned to the Miner class////  Author: Mat Buckland 2002 (fup@ai-junkie.com)////------------------------------------------------------------------------#include "State.h"class Miner;//------------------------------------------------------------------------////  In this state the miner will walk to a goldmine and pick up a nugget//  of gold. If the miner already has a nugget of gold he'll change state//  to VisitBankAndDepositGold. If he gets thirsty he'll change state//  to QuenchThirst//------------------------------------------------------------------------class EnterMineAndDigForNugget : public State
{private: EnterMineAndDigForNugget(){} //copy ctor and assignment should be private EnterMineAndDigForNugget(const EnterMineAndDigForNugget&); EnterMineAndDigForNugget& operator=(const EnterMineAndDigForNugget&);public: static EnterMineAndDigForNugget* Instance();public: virtual void Enter(Miner* miner); virtual void Execute(Miner* miner); virtual void Exit(Miner* miner);};//------------------------------------------------------------------------//// Entity will go to a bank and deposit any nuggets he is carrying. If the // miner is subsequently wealthy enough he'll walk home, otherwise he'll// keep going to get more gold//------------------------------------------------------------------------class VisitBankAndDepositGold : public State
{private: VisitBankAndDepositGold(){} //copy ctor and assignment should be private VisitBankAndDepositGold(const VisitBankAndDepositGold&); VisitBankAndDepositGold& operator=(const VisitBankAndDepositGold&);public: static VisitBankAndDepositGold* Instance(); virtual void Enter(Miner* miner); virtual void Execute(Miner* miner); virtual void Exit(Miner* miner);};//------------------------------------------------------------------------//// miner will go home and sleep until his fatigue is decreased// sufficiently//------------------------------------------------------------------------class GoHomeAndSleepTilRested : public State
{private: GoHomeAndSleepTilRested(){} //copy ctor and assignment should be private GoHomeAndSleepTilRested(const GoHomeAndSleepTilRested&); GoHomeAndSleepTilRested& operator=(const GoHomeAndSleepTilRested&);public: static GoHomeAndSleepTilRested* Instance(); virtual void Enter(Miner* miner); virtual void Execute(Miner* miner); virtual void Exit(Miner* miner);};//------------------------------------------------------------------------////------------------------------------------------------------------------class QuenchThirst : public State
{private: QuenchThirst(){} //copy ctor and assignment should be private QuenchThirst(const QuenchThirst&); QuenchThirst& operator=(const QuenchThirst&);public: static QuenchThirst* Instance(); virtual void Enter(Miner* miner); virtual void Execute(Miner* miner); virtual void Exit(Miner* miner);};#endif
#ifndef MINER_H#define MINER_H//------------------------------------------------------------------------////  Name:   Miner.h////  Desc:   A class defining a goldminer.////  Author: Mat Buckland 2002 (fup@ai-junkie.com)////------------------------------------------------------------------------#include 
#include
#include "BaseGameEntity.h"#include "Locations.h"#include "MinerOwnedStates.h"#include "StateMachine.h"//the amount of gold a miner must have before he feels comfortableconst int ComfortLevel = 5;//the amount of nuggets a miner can carryconst int MaxNuggets = 3;//above this value a miner is thirstyconst int ThirstLevel = 5;//above this value a miner is sleepyconst int TirednessThreshold = 5;class Miner : public BaseGameEntity{private: //an instance of the state machine class StateMachine
* m_pStateMachine; location_type m_Location; //how many nuggets the miner has in his pockets int m_iGoldCarried; int m_iMoneyInBank; //the higher the value, the thirstier the miner int m_iThirst; //the higher the value, the more tired the miner int m_iFatigue;public: Miner(int id):BaseGameEntity(id), m_Location(shack), m_iGoldCarried(0), m_iMoneyInBank(0), m_iThirst(0), m_iFatigue(0) { m_pStateMachine = new StateMachine
(this); m_pStateMachine->SetCurrentState(GoHomeAndSleepTilRested::Instance()); } ~Miner(){delete m_pStateMachine;} //this must be implemented void Update(); StateMachine
* GetFSM()const{
return m_pStateMachine;} location_type Location()const{
return m_Location;} void ChangeLocation(const location_type loc){m_Location=loc;} int GoldCarried()const{
return m_iGoldCarried;} void SetGoldCarried(const int val){m_iGoldCarried = val;} void AddToGoldCarried(const int val); bool PocketsFull()const{
return m_iGoldCarried >= MaxNuggets;} bool Fatigued()const; void DecreaseFatigue(){m_iFatigue -= 1;} void IncreaseFatigue(){m_iFatigue += 1;} int Wealth()const{
return m_iMoneyInBank;} void SetWealth(const int val){m_iMoneyInBank = val;} void AddToWealth(const int val); bool Thirsty()const; void BuyAndDrinkAWhiskey(){m_iThirst = 0; m_iMoneyInBank-=2;}};#endif

4. 完整代码示例(VS2010)

转载地址:http://jnyii.baihongyu.com/

你可能感兴趣的文章
国内有个码云,gitee
查看>>
原来我之前一直用的APM固件....现在很多东西明白了。
查看>>
realsense-ros里里程计相关代码
查看>>
似乎写个ROS功能包并不难,你会订阅话题发布话题,加点逻辑处理,就可以写一些基础的ROS功能包了。
查看>>
if __name__ == ‘__main__‘:就是Python里的main函数,脚本从这里开始执行,如果没有main函数则从上到下顺序执行。
查看>>
PX4官方用户和开发手册的首页面是会给你选择英文和中文的
查看>>
网络协议栈我是不是可以这么理解,就是把你要发送的数据自动处理成TCPIP格式的消息发出去,这种底层的转换不需要你弄了。
查看>>
除了LwIP还有uIP
查看>>
《跟工程师学嵌入式开发》这本书最后的终极项目我反而觉得有说头
查看>>
博士的申请考核制
查看>>
那些硬件的初始化函数主要是在做些上什么?
查看>>
MAVLink学习之路05_MAVLink应用编程接口分析(也有讲STM32下的收发函数)
查看>>
找到了中文版的mavlink手册
查看>>
浅谈飞控开发的仿真功能
查看>>
我觉得在室内弄无人机开发装个防撞机架还是很有必要的,TBUS就做得很好。
查看>>
serial也是见到很多次了,似乎它就是一种串行通信协议
查看>>
TBUS的一些信息
查看>>
PX4+激光雷达在gazebo中仿真实现(古月居)
查看>>
专业和业余的区别就在于你在基础在基本功打磨练习花的时间
查看>>
通过mavlink实现自主航线的过程笔记
查看>>