昨天在论坛看到了一关于状态迁移的帖子,心血来潮,写了一个C语言的实现。
时间仓促,没有做过多的测试和代码检查,供大家参考。
【题目】
一个保险箱上装了一个复合锁.锁有3个位置,分别标记为1、2、3,转盘可向左(L)或向右(R)转动。这样,在任意时刻转盘都有6种可能的运动,即1L.1R.2L.2R,3L和3R.保险箱的组合密码是IL.3R、2L,转盘的任何其他运动都将引起报警。图4.1描绘了保险箱的状态转换情况。有一个初始态.即保险箱锁定状态。若输人为1L.则下一个状态为A,但是,若输入不是1L而是转盘的任何其他移动,则下一个状态为“报警”.报警是两个终态之一(另一个终态是“保险箱解锁")。如果选择了转盘移动的正确组合,则保险箱状态转换的序列为从保险箱锁定到A再到B,最后到保险箱解锁,即另外一个终态。
题目详细参考下面链接
https://bbs.csdn.net/topics/396302075?page=1#post-411163261
【实现】
C实现语言如下,在VS2019调试通过。
#include <stdio.h>
#include <stdlib.h>
typedef enum
{
KEY_ACT_1L = 0,
KEY_ACT_1R,
KEY_ACT_2L,
KEY_ACT_2R,
KEY_ACT_3L,
KEY_ACT_3R,
KEY_ACT_MAX
}eKEY_ACT;
typedef enum
{
LOCK_STS_LOCKED = 0,
LOCK_STS_KEY_A_IN,
LOCK_STS_KEY_B_IN,
LOCK_STS_ALARM,
LOCK_STS_UNLOCK,
LOCK_STS_MAX
}eLOCK_STATUS;
#define eGET_ACT_STR( idx ) scpKEY_ACT_str[ ( idx ) ]
#define eGET_LOCK_STR( idx ) scpLOCK_STS_str[ ( idx ) ]
#define eGET_NEXT_MODE( currMode, act ) stMODE_TBL[ act ][ currMode ]
#define PTR printf_s
static const char *scpLOCK_STS_str [LOCK_STS_MAX] =
{
"LOCK_STS_LOCKED",
"LOCK_STS_KEY_A_IN",
"LOCK_STS_KEY_B_IN",
"LOCK_STS_ALARM",
"LOCK_STS_UNLOCK",
};
static const char* scpKEY_ACT_str[KEY_ACT_MAX] =
{
"KEY_ACT_1L",
"KEY_ACT_1R",
"KEY_ACT_2L",
"KEY_ACT_2R",
"KEY_ACT_3L",
"KEY_ACT_3R",
};
static const eLOCK_STATUS stMODE_TBL[6][3] =
{
{ LOCK_STS_KEY_A_IN, LOCK_STS_ALARM, LOCK_STS_ALARM },
{ LOCK_STS_ALARM, LOCK_STS_ALARM, LOCK_STS_ALARM },
{ LOCK_STS_ALARM, LOCK_STS_ALARM, LOCK_STS_UNLOCK },
{ LOCK_STS_ALARM, LOCK_STS_ALARM, LOCK_STS_ALARM },
{ LOCK_STS_ALARM, LOCK_STS_ALARM, LOCK_STS_ALARM },
{ LOCK_STS_ALARM, LOCK_STS_KEY_B_IN, LOCK_STS_ALARM }
};
int main( int argc, char* argv[] )
{
eLOCK_STATUS curr_mode = LOCK_STS_LOCKED;
eKEY_ACT e_act;
eLOCK_STATUS next_mode;
int cnt = 0, input_num;
while ( 1 )
{
do
{
PTR( "\nPlease input No. of the password as the following: " );
for ( cnt = 0; cnt < KEY_ACT_MAX; cnt++ )
{
PTR( "\n No.%01d %s ", cnt + 1, eGET_ACT_STR( cnt ) );
}
PTR("\n" );
scanf_s("%d", &input_num );
if ( (input_num <= 0) || (input_num > KEY_ACT_MAX) )
{
e_act = KEY_ACT_MAX;
PTR( "\n Your input is wrong!" );
}
else
{
e_act = (eKEY_ACT)(input_num - 1);
PTR( "\n Your input is right!" );
}
} while ( e_act == KEY_ACT_MAX );
next_mode = eGET_NEXT_MODE ( curr_mode, e_act );
PTR("\ncurr = [%s] Act = [%s] nextmode= [%s] ",
eGET_LOCK_STR( curr_mode ),
eGET_ACT_STR( e_act ),
eGET_LOCK_STR( next_mode )
);
if ( next_mode == LOCK_STS_ALARM)
{
PTR("\n Are you a pig?" );
break;
}
else if ( next_mode == LOCK_STS_UNLOCK )
{
PTR( "\n You are very clever." );
break;
}
else if ( next_mode >= LOCK_STS_ALARM )
{
PTR( "\n This is a bug." );
break;
}
else
{
/* Nothing to do */
}
curr_mode = next_mode;
};
return 0;
}