题目
一个开宝箱游戏的基本描述为:游戏中有多种类型的人物(Role),如战士(Solider)、魔法师(Mage)等,主角的类型只能选择其中一种,且游戏中不再更改。游戏中还有各种宝箱(Box),如装有不同数目金钱的宝箱、装有毒物的宝箱等。当任一种类型的主角打开装有金钱的宝箱时,宝箱中的金钱会增加给主角,同时宝箱的金钱数目变成0;当战士打开装有毒物的宝箱时,战士的生命值(HP)会减少10%,但金钱(Money)增加20%;当魔法师打开装有毒物的宝箱时,魔法师的生命值(HP)会减少30%,但金钱(Money)增加40% 。
请根据上述描述,给出相应类的设计并完整实现,要求你的设计应具有良好的扩展性,如增加新角色类型及箱子种类时,不需要修改已有的设计及实现。
代码
#include <iostream>
#include <string>
#include <sstream>
#include <typeinfo>
using namespace std;
class Role;
class Box
{
protected:
Box(int money) : money(money) {}
public:
int money;
virtual bool beOpenBy(Role& role) = 0;
virtual string toString()
{
stringstream ss;
ss << typeid(this).name() << "[Money:" << money << "]";
return ss.str();
}
};
class Role
{
protected:
Role(int hp, int money) : hp(hp), money(money) { }
public:
int hp, money;
virtual bool openBox(Box& box) = 0;
virtual string toString()
{
stringstream ss;
ss << typeid(this).name() << "[HP:" << hp << ",Money:" << money << "]";
return ss.str();
}
};
class Solider : public Role
{
public:
Solider() : Role(200, 50) { };
bool openBox(Box& box)
{
return box.beOpenBy(*this);
}
};
class Mage : public Role
{
public:
Mage() : Role(100, 100) { };
bool openBox(Box& box)
{
return box.beOpenBy(*this);
}
};
/*
宝箱名: 金钱宝箱
特性: 提高角色的金钱
*/
class MoneyBox : public Box
{
public:
MoneyBox() : Box(200) {};
bool beOpenBy(Role& role)
{
role.money += this->money;
this->money = 0;
return true;
}
};
/*
宝箱名: 毒宝箱
特性: 对角色造成伤害,并提高角色的金钱
*/
class PoisionBox : public Box
{
public:
PoisionBox() : Box(0) {};
bool beOpenBy(Role& role)
{
const auto& tpid = typeid(role);
if (tpid == typeid(Solider))
{
role.hp *= 0.9;
role.money *= 1.2;
return true;
} else if (tpid == typeid(Mage))
{
role.hp *= 0.7;
role.money *= 1.4;
return true;
} else
{
return role.openBox(*this);
}
}
};
//新增宝箱 对所有已存在的角色进行处理
/*
宝箱名: 剧毒宝箱
特性: 提高对角色的伤害,并提高角色的金钱收益
*/
class VeryPoisionBox : public Box
{
public:
VeryPoisionBox() : Box(0) {};
bool beOpenBy(Role& role)
{
const auto& tpid = typeid(role);
if (tpid == typeid(Solider))
{
role.hp *= 0.5;
role.money *= 1.4;
return true;
} else if (tpid == typeid(Mage))
{
role.hp *= 0.3;
role.money *= 1.6;
return true;
} else
{
return role.openBox(*this); //如果本宝箱无法处理该角色,则该角色在本宝箱之后添加, 所以 该角色能够处理本宝箱
}
}
};
//再新增角色 对所有已存在的宝箱进行处理
/*角色名:毒师
特性:增加对毒的抗性 提高从毒宝箱中获取的金钱数,降低受到毒宝箱的伤害,但是从金钱宝箱中获取的金钱数减少
*/
class Poisoner : public Role
{
public:
Poisoner() : Role(100, 100) { };
bool openBox(Box& box)
{
const auto& tpid = typeid(box);
if (tpid == typeid(MoneyBox))
{
this->money += box.money * 0.8;
box.money = 0;
return true;
} else if (tpid == typeid(PoisionBox))
{
this->hp *= 0.9;
this->money *= 1.6;
return true;
} else if (tpid == typeid(VeryPoisionBox))
{
this->hp *= 0.6;
this->money *= 2.0;
return true;
} else
{
return box.beOpenBy(*this); //如果本角色无法处理该宝箱,则该宝箱在本角色之后添加, 所以 该宝箱能够处理本角色;
}
}
};
int main()
{
Role& role = *new Poisoner();
Box& pbox = *new PoisionBox();
Box& box = *new MoneyBox();
Box& vpbox = *new VeryPoisionBox();
cout << role.toString() << endl;
cout << box.toString() << endl;
cout << pbox.toString() << endl;
cout << vpbox.toString() << endl;
role.openBox(box);
role.openBox(pbox);
role.openBox(vpbox);
cout << role.toString() << endl;
cout << box.toString() << endl;
cout << pbox.toString() << endl;
cout << vpbox.toString() << endl;
return 0;
}
————————————————
原文链接:https://blog.csdn.net/qq_37386833/article/details/100919779