何谓状态机
先附上百度上的一个解释:
举个最简单的例子。人有三个状态健康,感冒,康复中。触发的条件有淋雨(t1),吃药(t2),打针(t3),休息(t4)。所以状态机就是健康-(t4)->健康;健康-(t1)->感冒;感冒-(t3)->健康;感冒-(t2)->康复中;康复中-(t4)->健康,等等。就是这样状态在不同的条件下跳转到自己或不同状态的图。
类似于下图:
①淋雨 ②吃药 ③打针 ④休息
|------------| ① |-------|
| 健康 |----------------->| 感冒 |
|____________|<---------------- |_______|
↑ ↑ | ③ ↑ |
| |__| ①| |②
| ④ | ↓
| |--------|
|-------------------------| 康复中 |
④ |________|
下面附上代码实现
#include <iostream>
using namespace std;
void aManStateCheck(aMan* MAN);
void aManActionCheck(aMan* MAN);
void StateAfterAction(aMan* MAN);
typedef enum {
HEALTHY = 1,
COLD = 2,
RECOVERING= 3
}aManState;
typedef enum {
IN_RAIN = 1,
PILLS = 2,
INJECTION= 3,
REST = 4
}aManAction;
typedef struct {
int state;
int action;
}aMan;
aMan Harry = {1,4};
int main()
{
cout << "今天老菊也元气满满呢!\n";
while(1) {
aManStateCheck(&Harry);//状态检测
cout << "....." << endl;
cout << "老菊接下来做了啥:1、淋雨 2、吃药 3、打针 4、休息"<<endl;
cout << "....." << endl;
cin >> Harry.action; //外部动作输入
aManActionCheck(&Harry);//动作检测
}
}
//状态检测函数
void aManStateCheck(aMan* MAN) {
switch (MAN->state)
{
case HEALTHY:
cout<<"老菊很健康"<<endl;
break;
case COLD:
cout << "老菊感冒了" << endl;
break;
case RECOVERING:
cout << "康复中.." << endl;
break;
default:
break;
}
}
//动作检测函数
void aManActionCheck(aMan* MAN) {
switch(MAN->action)
{
case IN_RAIN:
cout << "淋雨.." << endl;
StateAfterAction(MAN);
break;
case PILLS:
cout << "吃药.." << endl;
StateAfterAction(MAN);
break;
case INJECTION:
cout << "打针.." << endl;
StateAfterAction(MAN);
break;
case REST:
cout << "休息.." << endl;
StateAfterAction(MAN);
break;
default:
cout << "???" << endl;
StateAfterAction(MAN);
break;
}
}
//最后执行
void StateAfterAction(aMan* MAN) {
switch (MAN->action)
{
case 1: //淋雨 :任何状态淋雨直接感冒
MAN->state = 2;
break;
case 2: //吃药 :感冒状态吃药-->康复中 其他状态吃药没变化
if (MAN->state == 2) {
MAN->state = 3;
}
else {
cout << "老菊状态没有改变" << endl;
}
break;
case 3://打针 :感冒打针-->健康 其他状态没变化
if (MAN->state == 2) {
MAN->state = 1;
cout << "老菊康复了呢" << endl;
}
else {
cout << "老菊状态没有改变" << endl;
}
break;
case 4: //休息 :健康、康复中-->健康 其他无变化
if (MAN->state == 3) {
MAN->state = 1;
cout << "老菊康复了呢" << endl;
}
else {
cout << "老菊状态没有改变" << endl;
}
break;
default: //
break;
}
}
可以看出,对于状态机而言。就是利用 switch。。。。case 语句来将状态着一列举出来。
首先我们可以将整个系统刻画出来。
整个系统可以用一个大的状态转移图来表示、真正执行动作的只有很小的一部分动作、(更加主要的是对于一些状态的处理)
对于状态机而言可能没有将代码量缩小(甚至可能增加了),但是对于代码的可读性、维护以及程序的简洁性会有一定的改善。