前提:因为最近打算学设计模式的状态模式,但不是很明白有限状态机和状态模式之间的关系,索性用C++实现了一个简单案例复习了一下FSM,如果有更好的实现方法,欢迎留言

有限状态机四大要素

  • 现态:当前所处状态
  • 次态:当条件满足后,即将转移的下一个状态
  • 动作:当满足某个事件时执行的动作;动作执行完毕后可以转移到另一个状态或保持原有状态
  • 条件:转移状态所需的条件,当满足条件时,会触发一个动作或进行状态转移

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++实现有限状态机相关推荐

  1. JavaScript 中的有限状态机

    http://www.ibm.com/developerworks/cn/web/wa-finitemach/ JavaScript 中的有限状态机 Page navigation 系列文章 有限状态 ...

  2. 确定有限状态机和非确定有限状态机详解 包含Java实现源码(Nondeterministic finite automata)

    本文将讲解确定有限自动状态机和非确定有限自动状态机的特点和区别.将结合图片例子重点讲解什么是非确定有限自动状态机.最后讲解如何将非确定状态机转换为确定的状态机.多图预警!! 有限自动状态机可以分为确定 ...

  3. 3d 行为树编辑器_cocos creator主程入门教程——有限状态机和行为树

    本篇介绍有限状态机和行为树.有限状态机用于有限的状态下的AI,由于同时只能处于一个状态,多个状态需要多个有限状态机,一般用于简单的AI行为.行为树是基于固定行为,通过遍历树来决定采用哪种行为.行为的设 ...

  4. 《数学之美》第12章 有限状态机—地图与本地搜索的核心技术

    智能手机的定位和导航功能,其实只有三项关键技术: 第一,利用卫星定位 第二,地址的识别 第三,根据用户输入的起点和终点,在地图上规划最短路线或者最快路线 1 地址分析和有限状态机 地址的识别和分析是本 ...

  5. 关于eigrp-FSM有限状态机的资料

    关于eigrp-FSM有限状态机的资料,PDF格式 从其它论坛下过来的,分享给大家 转载于:https://blog.51cto.com/kenjoe/138964

  6. JavaScript与有限状态机

    有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物. 简单说,它有三个特征: * 状态总数(state)是有限的. * 任一时刻,只处在一种状态之中. ...

  7. 「译」有限状态机在 CSS 动画中的应用

    原文地址:css-animations-with-finite-state-machines 原文作者:David Khourshid 译文出自:阿里云翻译小组 译文链接:github.com/daw ...

  8. HDLBits 系列(24)进入FSM(有限状态机)的世界入口

    目录 Fsm1 Fsm1s Fsm2 Fsm3comb Fsm1 This is a Moore state machine with two states, one input, and one o ...

  9. FPGA中有限状态机的状态编码采用格雷码还是独热码?

    今天看<从算法设计到硬件逻辑的实现>这本电子书时,遇到了一个问题,就是有限状态机的编写中,状态编码是采用格雷码还是独热码呢?究竟采用哪一种编码呢? 采用独热码为什么节省许多组合电路? 等等 ...

  10. 有限状态机设计实例之空调控制器(Verilog HDL语言描述)(仿真与综合)(附用Edraw(亿图)画状态转移图)

    目录 前言 空调控制器 简介 状态转移图如下: Verilog HDL语言描述 测试文件 仿真图 ISE综合 RTL Schematic Technology Schematic 前言 关于工具的使用 ...

最新文章

  1. jFreeChary初探
  2. matlab向量与x正方向的夹角_MIT—线性代数笔记25 对称矩阵和正定性
  3. web项目启动,运行方法
  4. 便利的操作plist文件
  5. 支付宝当面付扫码支付支付后不回调_科普:支付宝刷脸支付流程介绍
  6. ASP.NET中利用ashx实现图片防盗链
  7. java支付管理有源码_java支付宝支付案例源码
  8. OpenGL学习(二)第一个OpenGL程序,绘制三角形
  9. 大话存储pdf 百度网盘_学用系列|亲身体验百度网盘内测在线文档,有遗憾也有期待...
  10. 树莓派的wifi网络
  11. Java-创建图片验证码descriptor
  12. execution 排除_使用SQL Server 2016 Live Execution统计信息对SQL查询性能进行故障排除
  13. css标准流/非标准流 盒子模型
  14. AcWing 4241. 货物运输
  15. 使用 Flink Hudi 构建流式数据湖平台
  16. 趣味博弈论——斐波那契博弈
  17. C#技术分享【Word转换成图片和PDF——2种方案】
  18. 苹果手机编辑word_苹果手机更新后卡顿,关闭这两个开关立马恢复,设置之后差点泪崩...
  19. HashMap源码逐行分析
  20. JavaSwing_3.1: JPanel(面板)

热门文章

  1. 确界原理证明实数完备性定理
  2. 技术文档,完成课程表的抓包操作
  3. linux下制作动态库
  4. 如何在本地预览php文件
  5. JS添加事件和解绑事件:addEventListener()与removeEventListener()
  6. 一代霸主浏览器,彻底凉凉!
  7. 字节跳动Android实习面试凉凉经,面试总结
  8. 猴子选王c语言链表程序代码,数据结构(C语言)用栈和链表编写猴子选大王程序...
  9. linux系统下回车换行符
  10. YYModel V1.0.4源码解析