最近在研究怪物的AI,由于怪物的AI是使用有限状态机来实现的。所以就查看关于有限状态机的东西。根据这几天的查看资料,知道了有限状态机是计算机科学中一个很重要的概念。而且有限状态机是一个抽象的概念,具体实现是多种多样的。根据维基百科的介绍,它是这样的一个概念:
有限状态机
(
英语:finite-state machine
,
缩写
:
FSM
)又称
有限状态自动机
,简称
状态机
,是表示有限个
状态
以及在这些状态之间的转移和动作等行为的
数学模型
。
就像上面说的,既然是数学模型当然有很多的实现方法。其实最简单容易想到的方法就是使用switch case的写法:
- swtich(case)
- {
- case STATE1:
- do something;
- break;
- case STATE2:
- do something;
- break;
- .......
- }
- 但是这种写法会带来很多的问题,首先是当状态多的时候,switch case的语句会写的很长,使得可读性非常差。其次,可维护性也很差,每当要添加一个状态转换时,就要在Switch case添加相应的状态转换函数。会使得代码变得冗长,难以扩展。
- 当使用状态模式写状态机的时候,每一个状态就是一个类,添加状态只需要添加一个状态类就行了。在每一个类中实现相应的状态转换函数。
- 使用状态模式的好处:
- 1 每一个状态就是一个类,便于扩展,可读性高
- 2 每一个类有一个状态转换函数,使得整个代码的层次结构,很清晰
- 当然,没有一个东西是完美的。使用状态模式实现的时候,会使得类可能会变得很庞大。当总的来说,还是好处大于坏处的。毕竟代码不仅是出产品,还要考虑这个代码的扩展性还有可读性。一个只实现了功能,但扩展性很差,或者是除了你没有人看得懂,或者是很难看懂的代码,绝不是好代码。简单高效才是我们程序员追求的目标。
- 一个很简单的例子,仿照电梯的例子:
- /************************************************************************
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 )
{
coutgetLastState() != CLOSE_STATE)
coutm_stateMachine = new StateMachine();
this->m_stateMachine->init();
while (true) {
coutm_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,也使得整个的逻辑变得清晰可见。初探状态模式,还有些不足,以后改进!!(_~ ~_)
