《C++新经典设计模式》之第12章 状态模式
2023-12-15 23:36:51
《C++新经典设计模式》之第12章 状态模式
状态模式.cpp
#include <iostream>
#include <memory>
using namespace std;
// 用类表示状态, 一般用于有限状态机
// 状态机3部分组成:状态(State)、事件(Event)、动作(Action)
// 事件(转移条件, 触发状态变化的行为或动作)发生时, 状态改变, 可能执行动作
// 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类
// 3种角色
// Context(环境/上下文类),该类对象拥有多种状态以便对这些状态进行维护
// State(抽象状态类),定义接口以封装与环境类的特征状态相关的行为,声明不同状态对应的方法
// ConcreteState(具体状态类),实现与环境类该状态相关的行为
namespace ns1
{
class Monster // 怪物类
{
public:
enum MonsterState // 怪物状态枚举值
{
MonS_Fer, // 凶悍
MonS_Worr, // 不安
MonS_Fear, // 恐惧
MonS_Dead // 死亡
};
private:
int m_life; // 血量(生命值)
MonsterState m_status; // 初始状态
public:
Monster(int life, MonsterState status = MonS_Fer) : m_life(life), m_status(status) {}
public:
void Attacked(int power) // 怪物被攻击。参数power表示主角对怪物的攻击力(即怪物丢失的血量)
{
m_life -= power; // 怪物剩余的血量
switch (m_status)
{
case MonS_Fer:
if (m_life > 400)
{
cout << "monster " << power << " hurt, attact!" << endl;
// 处理其他动作逻辑比如反击
}
else if (m_life > 100)
{
cout << "monster " << power << " hurt, attact, help!" << endl;
m_status = MonS_Worr;
// 处理其他动作逻辑比如反击和呼唤支援
}
else if (m_life > 0)
{
cout << "monster " << power << " hurt, MonS_Fear, run!" << endl;
m_status = MonS_Fear;
// 处理其他动作逻辑比如逃跑
}
else
{
cout << "monster " << power << " hurt, dead!" << endl;
m_status = MonS_Dead;
// 处理怪物死亡后事宜比如怪物尸体定时消失等
}
break;
case MonS_Worr: // 目前怪物已经处于不安状态, 这说明怪物的血量<=400并且>100
if (m_life > 100)
{
cout << "monster " << power << " hurt, attact, help!" << endl;
// 处理其他动作逻辑比如反击和呼唤支援
}
else if (m_life > 0)
{
cout << "monster " << power << " hurt, MonS_Fear, run!" << endl;
m_status = MonS_Fear;
// 处理其他动作逻辑比如逃跑
}
else
{
cout << "monster " << power << " hurt, dead!" << endl;
m_status = MonS_Dead;
// 处理怪物死亡后事宜比如怪物尸体定时消失等
}
break;
case MonS_Fear:
if (m_life > 0)
{
cout << "monster " << power << " hurt, run!" << endl;
// 处理其他动作逻辑比如逃跑
}
else
{
cout << "monster " << power << " hurt, dead!" << endl;
m_status = MonS_Dead;
// 处理怪物死亡后事宜比如怪物尸体定时消失等
}
break;
default: // 怪物已经处于死亡状态
cout << "monster dead, cannot be attacketed!" << endl;
break;
}
}
};
}
namespace ns2
{
class Monster; // 类前向声明
class MonsterStatus // 怪物状态类
{
public:
virtual ~MonsterStatus() {}
virtual void Attacked(int power, Monster *const mainobj) = 0;
};
class MonsterStatus_Feroc : public MonsterStatus // 凶悍状态类
{
public:
// 传递进来的参数是否有必要使用, 开发者自行斟酌
void Attacked(int power, Monster *const mainobj) override
{
cout << "MonsterStatus_Feroc, attackt!" << endl;
// 处理其他动作逻辑比如反击
}
};
class MonsterStatus_Worr : public MonsterStatus // 不安状态类
{
public:
void Attacked(int power, Monster *const mainobj) override
{
cout << "MonsterStatus_Worr, attackt, help!" << endl;
// 处理其他动作逻辑比如反击和不停的呼唤支援
}
};
class MonsterStatus_Fear : public MonsterStatus // 恐惧状态类
{
public:
void Attacked(int power, Monster *const mainobj) override
{
cout << "MonsterStatus_Fear, run!" << endl;
// 处理其他动作逻辑比如逃跑
}
};
class MonsterStatus_Dead : public MonsterStatus // 死亡状态类
{
public:
void Attacked(int power, Monster *const mainobj) override
{
cout << "dead!" << endl;
// 处理怪物死亡后事宜比如怪物尸体定时消失等
}
};
class Monster // 怪物类
{
int m_life; // 血量(生命值)
shared_ptr<MonsterStatus> m_pState; // 持有状态对象
public:
Monster(int life, const shared_ptr<MonsterStatus> &pState = make_shared<MonsterStatus_Feroc>()) : m_life(life), m_pState(pState) {}
public:
void Attacked(int power)
{
int orglife = m_life; // 暂存原来的怪物血量值用于后续比较
m_life -= power; // 怪物剩余的血量
if (orglife > 400) // 怪物原来处于凶悍状态
{
if (m_life > 400) // 状态未变
{
// cout << "monster " << power << "点伤害并对主角进行疯狂的反击!" << endl;
m_pState->Attacked(power, this); // 其他的逻辑代码被本Monster类委托给了具体状态类来处理
}
else if (m_life > 100) // 状态从凶悍改变到不安
{
// cout << "monster " << power << "点伤害并对主角进行反击, 怪物变得焦躁不安并开始呼唤支援!" << endl;
m_pState.reset(new MonsterStatus_Worr()); // 怪物转到不安状态
m_pState->Attacked(power, this);
}
else if (m_life > 0) // 状态从凶悍状态改变到恐惧状态, 主角的攻击太恐怖了
{
// cout << "monster " << power << "点伤害, 怪物变得恐惧并开始逃跑!" << endl;
m_pState.reset(new MonsterStatus_Fear()); // 怪物转到恐惧状态
m_pState->Attacked(power, this);
}
else // 状态从凶悍改变到死亡
{
// cout << "monster " << power << "点伤害, 已经死亡!" << endl;
m_pState.reset(new MonsterStatus_Dead()); // 怪物转到死亡状态
m_pState->Attacked(power, this);
}
}
else if (orglife > 100) // 怪物原来处于不安状态
{
if (m_life > 100) // 状态未变
{
// cout << "monster " << power << "点伤害并对主角进行反击, 并继续急促的呼唤支援!" << endl;
m_pState->Attacked(power, this);
}
else if (m_life > 0) // 状态从不安改变到恐惧
{
// cout << "monster " << power << "点伤害, 怪物变得恐惧并开始逃跑!" << endl;
m_pState.reset(new MonsterStatus_Fear()); // 怪物转到恐惧状态
m_pState->Attacked(power, this);
}
else // 状态从不安改变到死亡
{
// cout << "monster " << power << "点伤害, 已经死亡!" << endl;
m_pState.reset(new MonsterStatus_Dead()); // 怪物转到死亡状态
m_pState->Attacked(power, this);
}
}
else if (orglife > 0) // 怪物原来处于恐惧状态
{
if (m_life > 0) // 状态未变
{
// cout << "monster " << power << "点伤害, 怪物继续逃跑!" << endl;
m_pState->Attacked(power, this);
}
else // 状态从恐惧改变到死亡
{
// cout << "monster " << power << "点伤害, 已经死亡!" << endl;
m_pState.reset(new MonsterStatus_Dead()); // 怪物转到死亡状态
m_pState->Attacked(power, this);
}
}
else // 怪物已经死亡
{
// 已经死亡的怪物, 状态不会继续发生改变
// cout << "怪物已死亡, 不能再被攻击!" << endl;
m_pState->Attacked(power, this);
}
}
};
}
namespace ns3
{
class Monster; // 类前向声明
class MonsterStatus // 怪物状态类
{
public:
virtual ~MonsterStatus() {}
virtual void Attacked(int power, Monster *const mainobj) = 0;
};
class MonsterStatus_Feroc : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
};
class MonsterStatus_Worr : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
};
class MonsterStatus_Fear : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
};
class MonsterStatus_Dead : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
};
class Monster // 怪物类定义
{
int m_life; // 血量(生命值)
shared_ptr<MonsterStatus> m_pState; // 持有状态对象
public:
Monster(int life, const shared_ptr<MonsterStatus> &pState = make_shared<MonsterStatus_Feroc>()) : m_life(life), m_pState(pState) {}
public:
void Attacked(int power) { m_pState->Attacked(power, this); } // 怪物被攻击
public:
int GetLife() const { return m_life; } // 获取怪物血量
void SetLife(int life) { m_life = life; } // 设置怪物血量
shared_ptr<MonsterStatus> getCurrentState() const { return m_pState; } // 获取怪物当前状态
void setCurrentState(const shared_ptr<MonsterStatus> &pState) { m_pState = pState; } // 设置怪物当前状态
};
void MonsterStatus_Feroc::Attacked(int power, Monster *const mainobj) // 凶悍状态类
{
int orglife = mainobj->GetLife(); // 暂存原来的怪物血量值用于后续比较
if ((orglife - power) > 400) // 怪物原来处于凶悍状态, 现在依旧处于凶悍状态
{
// 状态未变
mainobj->SetLife(orglife - power); // 怪物剩余的血量
cout << "MonsterStatus_Feroc, attackt!" << endl;
// 处理其他动作逻辑比如反击
}
else
{
// 不管下个状态是啥, 总之不会是凶悍状态, 只可能是不安、恐惧、死亡状态之一, 先无条件转到不安状态去(不安状态中会进行再次判断)
mainobj->setCurrentState(make_shared<MonsterStatus_Worr>());
// mainobj->getCurrentState()->Attacked(power, mainobj);
mainobj->Attacked(power);
}
}
void MonsterStatus_Worr::Attacked(int power, Monster *const mainobj) // 不安状态类
{
int orglife = mainobj->GetLife();
if ((orglife - power) > 100) // 怪物原来处于不安状态, 现在依旧处于不安状态
{
// 状态未变
mainobj->SetLife(orglife - power); // 怪物剩余的血量
cout << "MonsterStatus_Worr, attackt, help!" << endl;
// 处理其他动作逻辑比如反击和不停的呼唤支援
}
else
{
// 不管下个状态是啥, 总之不会是凶悍和不安状态, 只可能是恐惧、死亡状态之一, 先无条件转到恐惧状态去
mainobj->setCurrentState(make_shared<MonsterStatus_Fear>());
// mainobj->getCurrentState()->Attacked(power, mainobj);
mainobj->Attacked(power);
}
}
void MonsterStatus_Fear::Attacked(int power, Monster *const mainobj) // 恐惧状态类
{
int orglife = mainobj->GetLife();
if ((orglife - power) > 0) // 怪物原来处于恐惧状态, 现在依旧处于恐惧状态
{
// 状态未变
mainobj->SetLife(orglife - power); // 怪物剩余的血量
cout << "MonsterStatus_Fear, run!" << endl;
// 处理其他动作逻辑比如逃跑
}
else
{
// 不管下个状态是啥, 总之不会是凶悍、不安和恐惧状态, 只可能是死亡状态
mainobj->setCurrentState(make_shared<MonsterStatus_Dead>());
// mainobj->getCurrentState()->Attacked(power, mainobj);
mainobj->Attacked(power);
}
}
void MonsterStatus_Dead::Attacked(int power, Monster *const mainobj) // 死亡状态类
{
int orglife = mainobj->GetLife();
if (orglife > 0)
{
// 还要把怪物生命值减掉
mainobj->SetLife(orglife - power); // 怪物剩余的血量
// 处理怪物死亡后事宜比如怪物尸体定时消失等
}
cout << "dead!" << endl;
}
}
namespace ns4
{
class Monster; // 类前向声明
class MonsterStatus // 怪物状态类
{
public:
virtual ~MonsterStatus() {}
virtual void Attacked(int power, Monster *const mainobj) = 0;
};
class MonsterStatus_Feroc : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
public:
static shared_ptr<MonsterStatus> getInstance()
{
static shared_ptr<MonsterStatus> instance(new MonsterStatus_Feroc());
return instance;
}
};
class MonsterStatus_Worr : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
public:
static shared_ptr<MonsterStatus> getInstance()
{
static shared_ptr<MonsterStatus> instance(new MonsterStatus_Worr());
return instance;
}
};
class MonsterStatus_Fear : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
public:
static shared_ptr<MonsterStatus> getInstance()
{
static shared_ptr<MonsterStatus> instance(new MonsterStatus_Fear());
return instance;
}
};
class MonsterStatus_Dead : public MonsterStatus
{
public:
void Attacked(int power, Monster *const mainobj) override;
public:
static shared_ptr<MonsterStatus> getInstance()
{
static shared_ptr<MonsterStatus> instance(new MonsterStatus_Dead());
return instance;
}
};
class Monster // 怪物类定义
{
int m_life; // 血量(生命值)
shared_ptr<MonsterStatus> m_pState; // 持有状态对象
public:
Monster(int life, const shared_ptr<MonsterStatus> &pState = MonsterStatus_Feroc::getInstance()) : m_life(life), m_pState(pState) {}
public:
void Attacked(int power) { m_pState->Attacked(power, this); } // 怪物被攻击
public:
int GetLife() const { return m_life; } // 获取怪物血量
void SetLife(int life) { m_life = life; } // 设置怪物血量
shared_ptr<MonsterStatus> getCurrentState() const { return m_pState; } // 获取怪物当前状态
void setCurrentState(const shared_ptr<MonsterStatus> &pState) { m_pState = pState; } // 设置怪物当前状态
};
void MonsterStatus_Feroc::Attacked(int power, Monster *const mainobj) // 凶悍状态类
{
int orglife = mainobj->GetLife(); // 暂存原来的怪物血量值用于后续比较
if ((orglife - power) > 400) // 怪物原来处于凶悍状态, 现在依旧处于凶悍状态
{
// 状态未变
mainobj->SetLife(orglife - power); // 怪物剩余的血量
cout << "MonsterStatus_Feroc, attackt!" << endl;
// 处理其他动作逻辑比如反击
}
else
{
// 不管下个状态是啥, 总之不会是凶悍状态, 只可能是不安、恐惧、死亡状态之一, 先无条件转到不安状态去(不安状态中会进行再次判断)
mainobj->setCurrentState(MonsterStatus_Worr::getInstance());
// mainobj->getCurrentState()->Attacked(power, mainobj);
mainobj->Attacked(power);
}
}
void MonsterStatus_Worr::Attacked(int power, Monster *const mainobj) // 不安状态类
{
int orglife = mainobj->GetLife();
if ((orglife - power) > 100) // 怪物原来处于不安状态, 现在依旧处于不安状态
{
// 状态未变
mainobj->SetLife(orglife - power); // 怪物剩余的血量
cout << "MonsterStatus_Worr, attackt, help!" << endl;
// 处理其他动作逻辑比如反击和不停的呼唤支援
}
else
{
// 不管下个状态是啥, 总之不会是凶悍和不安状态, 只可能是恐惧、死亡状态之一, 先无条件转到恐惧状态去
mainobj->setCurrentState(MonsterStatus_Fear::getInstance());
// mainobj->getCurrentState()->Attacked(power, mainobj);
mainobj->Attacked(power);
}
}
void MonsterStatus_Fear::Attacked(int power, Monster *const mainobj) // 恐惧状态类
{
int orglife = mainobj->GetLife();
if ((orglife - power) > 0) // 怪物原来处于恐惧状态, 现在依旧处于恐惧状态
{
// 状态未变
mainobj->SetLife(orglife - power); // 怪物剩余的血量
cout << "MonsterStatus_Fear, run!" << endl;
// 处理其他动作逻辑比如逃跑
}
else
{
// 不管下个状态是啥, 总之不会是凶悍、不安和恐惧状态, 只可能是死亡状态
mainobj->setCurrentState(MonsterStatus_Dead::getInstance());
// mainobj->getCurrentState()->Attacked(power, mainobj);
mainobj->Attacked(power);
}
}
void MonsterStatus_Dead::Attacked(int power, Monster *const mainobj) // 死亡状态类
{
int orglife = mainobj->GetLife();
if (orglife > 0)
{
// 还要把怪物生命值减掉
mainobj->SetLife(orglife - power); // 怪物剩余的血量
// 处理怪物死亡后事宜比如怪物尸体定时消失等
}
cout << "dead!" << endl;
}
}
int main()
{
#if 0
using namespace ns1;
Monster monster(500, Monster::MonS_Fer);
cout << "Monster, MonS_Fer, 500 blood!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
#endif
#if 0
using namespace ns2;
Monster monster(500);
cout << "Monster, MonS_Fer, 500 blood!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
#endif
#if 0
using namespace ns3;
Monster monster(500);
cout << "Monster, MonS_Fer, 500 blood!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
#endif
#if 1
using namespace ns4;
Monster monster(500);
cout << "Monster, MonS_Fer, 500 blood!" << endl;
monster.Attacked(20);
monster.Attacked(100);
monster.Attacked(200);
monster.Attacked(170);
monster.Attacked(100);
monster.Attacked(100);
#endif
cout << "Over!\n";
return 0;
}
文章来源:https://blog.csdn.net/oqqyx1234567/article/details/128665751
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!