状态模式.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 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;
}