#include #include #include using namespace std; // a base class for characters. Eveyone builds off of this. class CharacterT { public: CharacterT(string n):name(n){} virtual ~CharacterT() = default; virtual string Fight(void) = 0; virtual string Name(void) const { return name; } private: string name; }; // two different skill classes. // perhaps this should be a heirarchy. class Fighter{ public: int Hit(void) const { return rand() % 10 + 1;} string HitDesc(void) const { return "Whomp";} string Title(void) const { return "Sir";} string Type(void) const {return "Fighter";} }; class Wizard{ public: int Hit(void) const { return rand() % 4 + 3;} string HitDesc(void) const { return "Zap";} string Title(void) const { return "Zapper";} string Type(void) const {return "Wizard";} }; // Race is a heirarchy. class RaceT { public: virtual ~RaceT()=default; virtual std::string RaceName(void) const {return "";} virtual int CauseDamage(void) const {return 0; } virtual int Heal(void) const {return 0;}; virtual int TakeDamage(void) const {return 0;}; }; class Elf: public RaceT{ public: string RaceName(void) const override { return "Elf"; } int CauseDamage(void) const override { return -1;} }; class Dwarf: public RaceT{ public: string RaceName(void) const override { return "Dwarf";} int CauseDamage(void) const override { return 2;} }; // A series of classes using mixin. template class PlayerT: public CharacterT, public T { public: PlayerT(string n): CharacterT(n) {} string Name() const override { return T::Title() + " " + CharacterT::Name(); } string Fight() override { return T::HitDesc() + " for " + to_string(T::Hit()); } }; template class RacePlayerT: public CharacterT, public Skill, public Race { public: RacePlayerT(string n): CharacterT(n) {} string Name() const override { return Skill::Title() + " " + CharacterT::Name() + " the " + Race::RaceName(); } string Fight() override { cout <<"The " << Race::RaceName() << " has a damage bonus of " << Race::CauseDamage() << " "; return Skill::HitDesc() + " for " + to_string(Skill::Hit() + Race::CauseDamage()); } }; template class DualPlayerT: public CharacterT, public Skill1, public Skill2 { public: DualPlayerT(string n): CharacterT(n) {} string Name() const override { return Skill1::Title() + "/" + Skill2::Title() + " " + CharacterT::Name(); } string Fight() override { if (rand() %2 ) { return Skill1::HitDesc() + " for " + to_string(Skill1::Hit()) + " as a " + Skill1::Type(); } else { return Skill2::HitDesc() + " for " + to_string(Skill2::Hit()) + " as a " + Skill2::Type(); } } }; class Peasant: public CharacterT { public: Peasant(string n): CharacterT(n){} string Fight() override { return "Run Away"; } }; int main() { vector players; players.push_back(new Peasant("Bilbo")); players.push_back(new PlayerT("Gandalf")); players.push_back(new PlayerT("Boromir")); players.push_back(new RacePlayerT("Glorfindel")); players.push_back(new RacePlayerT("Dain")); players.push_back(new RacePlayerT("Elron")); players.push_back(new RacePlayerT("Gimli")); players.push_back(new DualPlayerT("Elessar")); players.push_back(new DualPlayerT("Aragorn")); for(auto x: players) { cout << x->Name() << endl; for(int i=0; i < 4; i++) { cout << "\t" << x->Fight() << endl; } } return 0; }