状态模式.cpp
#include <iostream>
#include <memory>
using namespace std;
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) {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: 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) {m_pState->Attacked(power, this); }else if (m_life > 100) {m_pState.reset(new MonsterStatus_Worr()); m_pState->Attacked(power, this);}else if (m_life > 0) {m_pState.reset(new MonsterStatus_Fear()); m_pState->Attacked(power, this);}else {m_pState.reset(new MonsterStatus_Dead()); m_pState->Attacked(power, this);}}else if (orglife > 100) {if (m_life > 100) {m_pState->Attacked(power, this);}else if (m_life > 0) {m_pState.reset(new MonsterStatus_Fear()); m_pState->Attacked(power, this);}else {m_pState.reset(new MonsterStatus_Dead()); m_pState->Attacked(power, this);}}else if (orglife > 0) {if (m_life > 0) {m_pState->Attacked(power, this);}else {m_pState.reset(new MonsterStatus_Dead()); m_pState->Attacked(power, this);}}else {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->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->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->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->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->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->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 0using 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 0using 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 0using 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 1using 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);
#endifcout << "Over!\n";return 0;
}