本篇内容主要讲解“如何实现C++有限状态机”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何实现C++有限状态机”吧!
有限状态机四大要素
C++函数指针实现
现态:当前所处状态
次态:当条件满足后,即将转移的下一个状态
动作:当满足某个事件时执行的动作;动作执行完毕后可以转移到另一个状态或保持原有状态
条件:转移状态所需的条件,当满足条件时,会触发一个动作或进行状态转移
案例:学生的日常生活。
学生的日常生活包含以下几个状态:起床、上学、吃午饭、做作业、睡觉;
每个状态之间进行转移需要执行相应的事件。
我分为以下几个步骤来实现:
(1)绘制状态转移图
(2)创建状态转移的FSMItem类
枚举:所有状态State、所有事件Event;
成员变量:现态_curState、事件_event、次态_nextState
成员函数:动作函数
(3)创建有限状态机FSM类
成员变量:状态转移表vector<FSMItem*> _fsmTable
成员函数:初始化状态转移表、状态转移、根据事件执行相应动作
(4)测试FSM
(1)绘制状态转移图
(2)FSMItem类
//FSM状态项
class FSMItem
{
friend class FSM;
private:
//动作函数
static void getUp()
{
cout << "student is getting up!" << endl;
}
static void go2School()
{
cout << "student is going to school!" << endl;
}
static void haveLunch()
{
cout << "student is having lunch!" << endl;
}
static void doHomework()
{
cout << "student is doing homework!" << endl;
}
static void sleeping()
{
cout << "student is sleeping!" << endl;
}
public:
//枚举所有状态
enum State
{
GETUP = 0,
GOTOSCHOOL,
HAVELUNCH,
DOHOMEWORK,
SLEEP
};
//枚举所有事件
enum Events
{
EVENT1 = 0,
EVENT2,
EVENT3
};
public:
//初始化构造函数
FSMItem(State curState, Events event, void(*action)(), State nextState)
:_curState(curState), _event(event), _action(action), _nextState(nextState) {}
private:
State _curState; //现态
Events _event; //条件
void (*_action)(); //动作
State _nextState; //次态
};
(3)FSM类
class FSM
{
public:
//初始化状态机
FSM(FSMItem::State curState= FSMItem::GETUP):_curState(curState)
{
initFSMTable();
}
//状态转移
void transferState(FSMItem::State nextState)
{
_curState = nextState;
}
//根据当前状态和发生的事件,执行相应的动作,并进行状态转移
void handleEvent(FSMItem::Events event)
{
FSMItem::State curState = _curState; //现态
void (*action)() = nullptr;//动作
FSMItem::State nextState; //次态
bool flag = false;
for (int i = 0; i < _fsmTable.size(); i++)
{
if (event == _fsmTable[i]->_event && curState == _fsmTable[i]->_curState)
{
flag = true;
action = _fsmTable[i]->_action;
nextState = _fsmTable[i]->_nextState;
break;
}
}
//找到对应的状态项,执行动作,转移状态
if (flag)
{
if (action)
{
action();
}
transferState(nextState);
}
}
private:
//根据画的状态转移图初始化状态转移表
void initFSMTable()
{
_fsmTable.push_back(new FSMItem(FSMItem::GETUP, FSMItem::EVENT1, &FSMItem::getUp, FSMItem::GOTOSCHOOL));
_fsmTable.push_back(new FSMItem(FSMItem::GOTOSCHOOL, FSMItem::EVENT2, &FSMItem::go2School, FSMItem::HAVELUNCH));
_fsmTable.push_back(new FSMItem(FSMItem::HAVELUNCH, FSMItem::EVENT3, &FSMItem::haveLunch, FSMItem::DOHOMEWORK));
_fsmTable.push_back(new FSMItem(FSMItem::DOHOMEWORK, FSMItem::EVENT1, &FSMItem::doHomework, FSMItem::SLEEP));
_fsmTable.push_back(new FSMItem(FSMItem::SLEEP, FSMItem::EVENT2, &FSMItem::sleeping, FSMItem::GETUP));
}
public:
FSMItem::State _curState; //现态
private:
vector<FSMItem*> _fsmTable; //状态转移表
};
(4)测试FSM
#include<iostream>
#include<vector>
using namespace std;
//测试事件变换
void testEvent(FSMItem::Events& event)
{
switch (event)
{
case FSMItem::EVENT1:
event = FSMItem::EVENT2;
break;
case FSMItem::EVENT2:
event = FSMItem::EVENT3;
break;
case FSMItem::EVENT3:
event = FSMItem::EVENT1;
break;
}
}
int main()
{
FSM *fsm = new FSM();
auto event = FSMItem::EVENT1;
while (1)
{
cout << "event " << event << " is coming..." << endl;
fsm->handleEvent(event);
cout << "fsm current state is " << fsm->_curState << endl;
testEvent(event);
}
return 0;
}
到此,相信大家对“如何实现C++有限状态机”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。