您当前的位置: 首页 >  c++

phymat.nico

暂无认证

  • 0浏览

    0关注

    1967博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

有限状态机(使用状态模式C++实现)

phymat.nico 发布时间:2017-12-11 13:56:24 ,浏览量:0

最近在研究怪物的AI,由于怪物的AI是使用有限状态机来实现的。所以就查看关于有限状态机的东西。根据这几天的查看资料,知道了有限状态机是计算机科学中一个很重要的概念。而且有限状态机是一个抽象的概念,具体实现是多种多样的。根据维基百科的介绍,它是这样的一个概念: 有限状态机 ( 英语:finite-state machine , 缩写 : FSM )又称 有限状态自动机 ,简称 状态机 ,是表示有限个 状态 以及在这些状态之间的转移和动作等行为的 数学模型 。

  就像上面说的,既然是数学模型当然有很多的实现方法。其实最简单容易想到的方法就是使用switch case的写法:

[cpp] view plain copy
  1. swtich(case)  
  2. {  
  3. case STATE1:  
  4.         do something;  
  5.         break;  
  6. case STATE2:  
  7.         do something;  
  8.         break;  
  9. .......  
  10. }  
[cpp] view plain copy
  1. 但是这种写法会带来很多的问题,首先是当状态多的时候,switch case的语句会写的很长,使得可读性非常差。其次,可维护性也很差,每当要添加一个状态转换时,就要在Switch case添加相应的状态转换函数。会使得代码变得冗长,难以扩展。  
[cpp] view plain copy
  1. 当使用状态模式写状态机的时候,每一个状态就是一个类,添加状态只需要添加一个状态类就行了。在每一个类中实现相应的状态转换函数。  
[cpp] view plain copy
  1. 使用状态模式的好处:  
[cpp] view plain copy
  1. 1 每一个状态就是一个类,便于扩展,可读性高  
[cpp] view plain copy
  1. 2 每一个类有一个状态转换函数,使得整个代码的层次结构,很清晰  
[cpp] view plain copy
  1. 当然,没有一个东西是完美的。使用状态模式实现的时候,会使得类可能会变得很庞大。当总的来说,还是好处大于坏处的。毕竟代码不仅是出产品,还要考虑这个代码的扩展性还有可读性。一个只实现了功能,但扩展性很差,或者是除了你没有人看得懂,或者是很难看懂的代码,绝不是好代码。简单高效才是我们程序员追求的目标。  
[cpp] view plain copy
  1. 一个很简单的例子,仿照电梯的例子:  
[cpp] view plain copy
  1. /************************************************************************  
        Des: 状态机,负责状态的装换
************************************************************************/
#include "statemachine.h"
#include "StateDefine.h"
using namespace std;
StateMachine::StateMachine()
{
//起始的状态为停止状态
    m_currentState = m_lastState = STOP_STATE;
}
StateMachine::~StateMachine()
{
}
/**
 * @brief 状态机的初始化函数,负责把每一个状态的类放入Map中进行管理
 */
void StateMachine::init()
{
    m_stateManager[0] = new CloseState();
    m_stateManager[1] = new OpenState();
    m_stateManager[2] = new UpState();
    m_stateManager[3] = new DownState();
    m_stateManager[4] = new StopState();
    (m_stateManager[4])->handle(this);
}
/**
 * @brief 状态装换函数,当需要切换状态的时候,只需要调用此函数
 * @param stateId :每一个状态都有一个相应的ID,定义在StateDefine的头文件中
 */
void StateMachine::changeState(int stateId)
{
    if( stateId == m_currentState )
    {
        cout
getLastState() != CLOSE_STATE)
            cout
m_stateMachine = new StateMachine();
    this->m_stateMachine->init();
    while (true) {
        cout
m_stateMachine->changeState(CLOSE_STATE);
        }
        else if( !strcmp(str,"o"))
        {
            this->m_stateMachine->changeState(OPEN_STATE);
        }
        else if( !strcmp(str,"u"))
        {
            this->m_stateMachine->changeState(UP_STATE);
        }
        else if( !strcmp(str,"d"))
        {
            this->m_stateMachine->changeState(DOWN_STATE);
        }
        else if( !strcmp(str,"s"))
        {
            this->m_stateMachine->changeState(STOP_STATE);
        }
    }
}
使用状态模式确实使得使用避免过度的使用了IF ELSE 或者是Switch case,也使得整个的逻辑变得清晰可见。初探状态模式,还有些不足,以后改进!!(_~ ~_) 大笑
[cpp] view plain copy
  1.   
关注
打赏
1659628745
查看更多评论
立即登录/注册

微信扫码登录

0.0462s