有限状态机(Finite-state machine)又称有限状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。常用与:正则表达式引擎,编译器的词法和语法分析,游戏设计,网络协议,企业应用中等方面。

状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果关系的考虑。
“现态”和“条件”是因,“动作”和“次态”是果。
1. 现态:是指当前所处的状态。
2. 条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
3. 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态 。
4. 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

有限状态机 FSM 实现

用while{switch/case}(推荐可读性高) 或 if/else 实现,简单粗暴,适合简单的小型状态机;
用设计模式中的 state pattern,把复杂判断的逻辑简化,利于组织代码;
用状态表设计,建立状态表和动作查询表,根据状态表、事件、动作表定位相应的动作处理函数,执行完成后再进行状态的切换;

函数指针实现的FSM的实例

// https://github.com/AstarLight/FSM-framework/blob/master/main.c
#include <stdio.h>
//#include <windows.h> //windows
#include <unistd.h> //linux //比如我们定义了小明一天的状态如下
enum
{
GET_UP,
GO_TO_SCHOOL,
HAVE_LUNCH,
DO_HOMEWORK,
SLEEP,
}; //我们定义的事件有以下几个
enum
{
EVENT1 = ,
EVENT2,
EVENT3,
}; typedef struct FsmTable_s
{
int event; //事件
int CurState; //当前状态
void (*eventActFun)(); //函数指针
int NextState; //下一个状态
}FsmTable_t; typedef struct FSM_s
{
FsmTable_t* FsmTable; //指向的状态表
int curState; //FSM当前所处的状态 }FSM_t; int g_max_num; //状态表里含有的状态个数 void GetUp()
{
// do something
printf("xiao ming gets up!\n"); } void Go2School()
{
// do something
printf("xiao ming goes to school!\n");
} void HaveLunch()
{
// do something
printf("xiao ming has lunch!\n");
} void DoHomework()
{
// do something
printf("xiao ming does homework!\n");
} void Go2Bed()
{
// do something
printf("xiao ming goes to bed!\n");
} /*状态机注册*/
void FSM_Regist(FSM_t* pFsm, FsmTable_t* pTable)
{
pFsm->FsmTable = pTable;
} /*状态迁移*/
void FSM_StateTransfer(FSM_t* pFsm, int state)
{
pFsm->curState = state;
} /*事件处理*/
void FSM_EventHandle(FSM_t* pFsm, int event)
{
FsmTable_t* pActTable = pFsm->FsmTable;
void (*eventActFun)() = NULL; //函数指针初始化为空
int NextState;
int CurState = pFsm->curState;
int flag = ; //标识是否满足条件 /*获取当前动作函数*/
for (int i = ; i<g_max_num; i++)
{
//当且仅当当前状态下来个指定的事件,我才执行它
if (event == pActTable[i].event && CurState == pActTable[i].CurState)
{
flag = ;
eventActFun = pActTable[i].eventActFun;
NextState = pActTable[i].NextState;
break;
}
} if (flag) //如果满足条件了
{
/*动作执行*/
if (eventActFun)
{
eventActFun();
} //跳转到下一个状态
FSM_StateTransfer(pFsm, NextState);
}
else
{
// do nothing
}
} FsmTable_t XiaoMingTable[] =
{
//{到来的事件,当前的状态,将要要执行的函数,下一个状态}
{ EVENT1, SLEEP, GetUp, GET_UP },
{ EVENT2, GET_UP, Go2School, GO_TO_SCHOOL },
{ EVENT3, GO_TO_SCHOOL, HaveLunch, HAVE_LUNCH },
{ EVENT1, HAVE_LUNCH, DoHomework, DO_HOMEWORK },
{ EVENT2, DO_HOMEWORK, Go2Bed, SLEEP }, //add your codes here
}; //初始化FSM
void InitFsm(FSM_t* pFsm)
{
g_max_num = sizeof(XiaoMingTable) / sizeof(FsmTable_t);
pFsm->curState = SLEEP;
FSM_Regist(pFsm, XiaoMingTable);
} //测试用的
void test(int *event)
{
if (*event == )
{
*event = ;
}
else
{
(*event)++;
} } int main()
{
FSM_t fsm;
InitFsm(&fsm);
int event = EVENT1;
//小明的一天,周而复始的一天又一天,进行着相同的活动
while ()
{
printf("event %d is coming...\n", event);
FSM_EventHandle(&fsm, event);
printf("fsm current state %d\n", fsm.curState);
test(&event);
sleep(); //休眠1秒,方便观察
} return ;
}

有限状态机FSM的更多相关文章

  1. 有限状态机FSM(自动售报机Verilog实现)

    有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...

  2. cocos2d-x 游戏开发之有限状态机(FSM) (四)

    cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge ...

  3. cocos2d-x 游戏开发之有限状态机(FSM) (三)

    cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monk ...

  4. cocos2d-x 游戏开发之有限状态机(FSM) (一)

    cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...

  5. cocos2d-x 游戏开发之有限状态机(FSM) (二)

    cocos2d-x 游戏开发之有限状态机(FSM)  (二) 1 状态模式

  6. Atitit. 有限状态机 fsm 状态模式

    Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...

  7. [原创][FPGA]有限状态机FSM学习笔记(一)

    1. 概述--何为有限状态机FSM? 有限状态机-Finite State Machine,简写为FSM,是表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.通常 ...

  8. Linux编程之有限状态机FSM的理解与实现

    有限状态机(finite state machine)简称FSM,表示有限个状态及在这些状态之间的转移和动作等行为的数学模型,在计算机领域有着广泛的应用.FSM是一种逻辑单元内部的一种高效编程方法,在 ...

  9. 有限状态机(FSM)的Java 学习FSM

    本文从简单的例子入手,逐步演变成非常复杂的程序. 在简明 状态模式(5.8)中,状态之间的变换由外界控制,或者说,多种状态是分割的.无关的.状态模式最有趣的地方正是讨论其状态的变迁. 1.引子 空调( ...

随机推荐

  1. dw擴展jquery

    https://jingyan.baidu.com/article/90895e0fbbb65764ec6b0bd1.html

  2. C#里XML(JSON)序列化时,自动隐藏值为Null的成员的输出

    从StackOverflow里找到的答案.发现对最新的Newtownsoft的JSON序列化也同样适用. https://stackoverflow.com/questions/5818513/xml ...

  3. How to convert mkv to mp4 lossless

    ffmpeg -i example.mkv -vcodec copy -acodec copy example.mp4

  4. mysql必须知道的

    https://blog.csdn.net/xlgen157387/article/details/73691848

  5. 51nod-1445-变色DNA(最短路)

    题意:题目是说从0到n-1,我还是习惯从1到n,所以以下我都这么写,大概题意就是(i, j)==‘Y’表示可以从i颜色变成j颜色,然后问我们最少删除几个会影响结果的‘Y’,能到n这个颜色: 没有意义的 ...

  6. ElasticHD Linux环境下安装

    ElasticHD Linux环境下安装教程        ElasticHD windows环境下安装教程   上一篇讲了ElasticHD windows环境下安装,这一篇继续说明ElasticH ...

  7. web页面简单布局的修改,测试中的应用

    在做功能测试的时候发现,界面显示不美观,觉得登录按钮应向上移动,那么如何移动呢? 很简单:使用开发者工具找到这个按钮所在的div,修改其中的属性值,top值减小,即可实现按钮向上移动,具体可以看效果

  8. Catch the Theves HDU - 3870(s - t平面图最小割)

    题意: 板题...建个图..跑一遍spfa就好了...嘻嘻... 注意..数组大小就好啦..400 * 400 = 1600 我也是抑郁了..沙雕的我.. #include <iostream& ...

  9. 微信小程序原生开发简介

    简介: 总结: 1. 逻辑层使用js引擎,视图层使用webview渲染 2. 微信小程序已经支持了绝大部分的 ES6 API 3. 可以自动补全css的兼容语法 文档:https://develope ...

  10. HNOI2019总结

    HNOI2019总结 Day 1 开场看三道题,T1是个计算几何,T2是个操作树加\(border\),T3题意有点复杂.想T1想了半个多小时,发现那个钝角不是很会处理,但是40分暴力应该还是可以写, ...