状态迁移的C语言实现实例

昨天在论坛看到了一关于状态迁移的帖子,心血来潮,写了一个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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值