设计模式State之模式

设计模式中的State模式是比较常用的模式之一,通常一个简单的AI系统会使用状态机模式.

这里我将详述简单AI系统中的状态机模式..

为此,这个简单的AI系统将会模拟一个苦逼的工人,这个工人每天要做4件事,睡觉,洗漱,吃饭,挖矿..为了做这4件事这个工人还要分别前往4个地点,分别对应的家(睡觉),,澡堂(洗漱),,餐厅(吃饭),矿场(挖矿)..

工人会在适当的条件下变换不同的状态,为此我们要准备一个状态表,描述各个状态之间转换的信息

//------------------------------------------------
//human类的状态变化表
//状态1			转换条件					状态2
//睡觉			体力恢复到100				挖矿
//洗漱			清醒恢复到100				挖矿
//吃饭			能量恢复到100				挖矿
//挖矿          		体力减到10				睡觉
//挖矿			清醒减到50				洗漱
//挖矿			能量减到70				吃饭
//挖矿			赚了钱100				退休
//------------------------------------------------


工人会不停的干活直到他觉得饿了(能量减少到70)就去餐厅吃饭,或者体力减少到10就回家睡觉,或者清醒度减少的50就去洗澡,否则就继续挖矿

为此需要实现一个状态基类

class cState
{
public:
	cState(void);
	~cState(void);
	virtual void Execute(cHuman* human)=0;	//执行状态
	virtual void Enter(cHuman* human)=0;	//进入状态前的操作
	virtual void Exit(cHuman* human)=0;		//推出状态前的操作
};


接下来就是实现四个状态的类,他们都继承与上面这个基类

//sleep--------------------------------------------------
class cSleepState:public cState
{
	cSleepState(void){}
public:
	~cSleepState(void){}
	virtual void Execute(cHuman* human);
	virtual void Enter(cHuman* human);
	virtual void Exit(cHuman* human);
	static cSleepState* Instance();
};
//wash----------------------------------------------------
class cWashState:public cState
{
	cWashState(void){}
public:
	~cWashState(void){}
	virtual void Execute(cHuman* human);
	virtual void Enter(cHuman* human);
	virtual void Exit(cHuman* human);
	static cWashState* Instance();
};
//eat-----------------------------------------------------
class cEatState:public cState
{
	cEatState(void){}
public:
	~cEatState(void){}
	virtual void Execute(cHuman* human);
	virtual void Enter(cHuman* human);
	virtual void Exit(cHuman* human);
	static cEatState* Instance();
};
//make money----------------------------------------------
class cMakeMoneyState:public cState
{
	cMakeMoneyState(void){}
public:
	~cMakeMoneyState(void){}
	virtual void Execute(cHuman* human);
	virtual void Enter(cHuman* human);
	virtual void Exit(cHuman* human);
	static cMakeMoneyState* Instance();
};

#include "cState.h"
#include "cHuman.h"
#include <iostream>
using namespace std;
cState::cState(void)
{
}


cState::~cState(void)
{
}

//sleep------------------------------------------------
void cSleepState::Execute(cHuman* human)
{
	if(!human)
		return;

	human->Sleep();

	if(human->IsFullPower())
		human->ChangeState(cMakeMoneyState::Instance());
}
void cSleepState::Enter(cHuman* human)
{
	human->m_fMoney-=0;
	human->ChangeLocal(human_local::home);
	cout<<"回家睡觉去了.."<<endl;
}
void cSleepState::Exit(cHuman* human)
{
	cout<<"离开家,工作去了.."<<endl;
}

cSleepState* cSleepState::Instance()
{
	static cSleepState g_sleepState;
	return &g_sleepState;
}

//wash-------------------------------------------------
void cWashState::Execute(cHuman* human)
{
	if(!human)
		return;

	human->Wash();

	if(human->IsFullWake())
		human->ChangeState(cMakeMoneyState::Instance());
}
void cWashState::Enter(cHuman* human)
{
	human->m_fMoney-=2;
	human->ChangeLocal(human_local::shower);
	cout<<"干了这么久,衣服都脏了,去澡堂洗个澡吧.."<<endl;
}
void cWashState::Exit(cHuman* human)
{
	cout<<"洗完澡就是舒服,离开澡堂.."<<endl;
}

cWashState* cWashState::Instance()
{
	static cWashState g_washState;
	return &g_washState;
}

//eat--------------------------------------------------
void cEatState::Execute(cHuman* human)
{
	if(!human)
		return;

	human->Eat();

	if(human->IsFullEnerger())
		human->ChangeState(cMakeMoneyState::Instance());
}
void cEatState::Enter(cHuman* human)
{
	human->m_fMoney-=3;
	human->ChangeLocal(human_local::restaurant);
	cout<<"肚子饿了,吃饭去了,去餐厅.."<<endl;
}
void cEatState::Exit(cHuman* human)
{
	cout<<"酒足饭饱,离开餐厅.."<<endl;
}

cEatState* cEatState::Instance()
{
	static cEatState g_eatState;
	return &g_eatState;
}

//make money---------------------------------------------
void cMakeMoneyState::Execute(cHuman* human)
{
	if(!human)
		return;

	human->MakeMoney();

	if(human->IsLowEnerger())
		human->ChangeState(cEatState::Instance());
	else if(human->IsLowPower())
		human->ChangeState(cSleepState::Instance());
	else if(human->IsLowWake())
		human->ChangeState(cWashState::Instance());
}
void cMakeMoneyState::Enter(cHuman* human)
{
	human->ChangeLocal(human_local::mine);
	cout<<"又要去干活了,去矿场.."<<endl;
}
void cMakeMoneyState::Exit(cHuman* human)
{
	cout<<"离开矿场.."<<endl;
}

cMakeMoneyState* cMakeMoneyState::Instance()
{
	static cMakeMoneyState g_makeMoneyState;
	return &g_makeMoneyState;
}


 

//以上是和状态相关的代码,接下来就实现一个工人类,代码都比较简单,一目了然

#pragma once
#include "GlobalDef.h"
#include "cState.h"
class cHuman
{
public:
	cHuman(void);
	~cHuman(void);
	void Sleep();
	void Wash();
	void Eat();
	void MakeMoney();

	bool IsLowPower();
	bool IsLowWake();
	bool IsLowEnerger();
	bool IsLowMoney();

	bool IsFullPower();
	bool IsFullWake();
	bool IsFullEnerger();
	bool IsFullMoney();

	void Update();
	void ChangeLocal(human_local local);
	void ChangeState(cState* state);
//private:
	//void GoHome();
	//void GoShower();
	//void GoRestaurant();
	//void GoMine();
	cState* m_curState;
	float m_fPower;		//体力
	float m_fWake;		//清醒度
	float m_fEnerger;	//能量
	float m_fMoney;		//钱
	human_local m_eLocal;
};

 

#include "cHuman.h"
#include <iostream>
#include <stdio.h>
using namespace std;
cHuman::cHuman(void)
{
	m_fPower=70;
	m_fWake=100;	
	m_fEnerger=100;	
	m_fMoney=10;
	m_eLocal=human_local::home;
	m_curState=cSleepState::Instance();
}


cHuman::~cHuman(void)
{
}

void cHuman::Sleep()
{
	cout<<"睡觉中ZZZZZzzz.. 体力="<<m_fPower<<endl;
	m_fPower+=30;
}
void cHuman::Wash()
{
	cout<<"洗澡.. 清醒="<<m_fWake<<endl;
	m_fWake+=30;
}
void cHuman::Eat()
{
	cout<<"吃饭.. 能量="<<m_fEnerger<<endl;
	m_fEnerger+=30;
}
void cHuman::MakeMoney()
{
	cout<<"赚钱.. 钱="<<m_fMoney<<endl;
	m_fMoney++;
	m_fPower-=5;
	m_fWake-=5;
	m_fEnerger-=5;
}

//void cHuman::GoHome()
//{
//	cout<<"回家...;"<<endl;
//}
//void cHuman::GoShower()
//{
//	cout<<"去澡堂...;"<<endl;
//}
//void cHuman::GoRestaurant()
//{
//	cout<<"去饭店...;"<<endl;
//}
//void cHuman::GoMine()
//{
//	cout<<"去矿场...;"<<endl;
//}

bool cHuman::IsLowPower()
{
	return m_fPower>MIN_POWER?false:true;
}
bool cHuman::IsLowWake()
{
	return m_fWake>MIN_WAKE?false:true;
}
bool cHuman::IsLowEnerger()
{
	return m_fEnerger>MIN_ENERGER?false:true;
}
bool cHuman::IsLowMoney()
{
	return m_fMoney>1?false:true;
}

//-------------------------------
bool cHuman::IsFullPower()
{
	return m_fPower>100?true:false;
}
bool cHuman::IsFullWake()
{
return m_fWake>100?true:false;
}
bool cHuman::IsFullEnerger()
{
return m_fEnerger>100?true:false;
}
bool cHuman::IsFullMoney()
{
return m_fMoney>100?true:false;
}

void cHuman::ChangeLocal(human_local local)
{
	m_eLocal=local;
}
void cHuman::ChangeState(cState* state)
{
	if(!state)
		return;
	m_curState->Exit(this);
	m_curState=state;
	m_curState->Enter(this);
}

void cHuman::Update()
{
	if(m_curState)
		m_curState->Execute(this);
}



 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值