Suppose that you are creating a fantasy role-playing game. In this game, we have four different types of creatures: humans, cyberdemons, balrogs, and elves. To represent one of these creatures, we might define a Creature class as follows:
class Creature
{
private:
int type;
// 0 human, 1 cyberdemon, 2 balrog, 3 elf
int strength;
// How much damage we can inflict
int hitpoints; // How much damage we can sustain
string getSpecies(); // Returns type of species
public:
Creature( );
// Initialize to human, 10 strength, 10 hit points
Creature(int newType, int newStrength, int newHit);
// Initialize creature to new type, strength, hit points
// Also add appropriate accessor and mutator functions
// for type, strength, and hit points
int getDamage();
// Returns amount of damage this creature
// inflicts in one round of combat
};
Here is an implementation of the getSpecies( ) function:
string Creature::getSpecies()
{
switch (type)
{
case 0: return "Human";
case 1: return "Cyberdemon";
case 2: return "Balrog";
case 3: return "Elf";
}
return "Unknown";
}
The getDamage( ) function outputs and returns the damage this creature can inflict in one round of combat. The rules for calculating the damage are as follows:
■ Every creature inflicts damage that is a random number r, where 0 < r <=
strength .
■ Demons have a 5% chance of inflicting a demonic attack, which is an additional 50 damage points. Balrogs and Cyberdemons are demons.
■ Elves have a 10% chance to inflict a magical attack that doubles the normalamount of damage.
■ Balrogs are very fast, so they get to attack twice.
An implementation of getDamage( ) is given here:
int Creature::getDamage( )
{
int damage;
// All creatures inflict damage, which is a
// random number up to their strength
damage = (rand( ) % strength) + 1;
cout << getSpecies( ) << " attacks for " <<
damage << " points!" << endl;
// Demons can inflict damage of 50 with a 5% chance
if ((type = 2) || (type == 1))
if ((rand( ) % 100) < 5)
{
damage = damage + 50;
cout << "Demonic attack inflicts 50 "
<< " additional damage points!" << endl;
}
// Elves inflict double magical damage with a 10% chance
if (type == 3)
{
if ((rand( ) % 10)==0)
{
cout << "Magical attack inflicts " << damage <<
" additional damage points!" << endl;
damage = damage * 2;
}
}
// Balrogs are so fast they get to attack twice
if (type == 2)
{
int damage2 = (rand() % strength) + 1;
cout << "Balrog speed attack inflicts " << damage2 <<
" additional damage points!" << endl;
damage = damage + damage2;
}
return damage;
}
One problem with this implementation is that it is unwieldy to add new creatures. Rewrite the class to use inheritance, which will eliminate the need for the variable type . The Creature class should be the base class. The classes Demon, Elf, and Human should be derived from Creature . The classes Cyberdemon and Balrog should be derived from Demon . You will need to rewrite the getSpecies( ) and getDamage( ) functions so they are appropriate for each class.
For example, the getDamage( ) function in each class should only compute the damage appropriate for that object. The total damage is then calculated by combining the results of getDamage( ) at each level of the inheritance hierarchy. As an example, invoking getDamage( ) for a Balrog object should invoke getDamage( ) for the Demon object, which should invoke getDamage( ) for the Creature object. This will compute the basic damage that all creatures inflict, followed by the random 5% damage that demons inflict, followed by the double damage that balrogs inflict.
Also include mutator and accessor functions for the private variables. Write a main function that contains a driver to test your classes. It should create an object for each type of creature and repeatedly outputs the results of getDamage( ) .
#include <iostream>
#include <cstdlib>
#include <string>
#include <ctime>
using namespace std;
class Creature {
public:
Creature();
Creature(int newStrength, int newHit);
int getDamage() const;
int getStrength() const;
int getHitpoints() const;
string getSpecies() const;
void setStrength(int newStrength);
void setHitpoints(int newHit);
void setSpecies(string newSpecies);
private:
int strength;
int hitpoints;
string species;
};
class Demon : public Creature {
public:
Demon();
Demon(int newStrength, int newHit);
int getDamage() const;
};
class Elf : public Creature {
public:
Elf();
Elf(int newStrength, int newHit);
int getDamage() const;
};
class Human : public Creature {
public:
Human();
Human(int newStrength, int newHit);
};
class Balrog : public Demon {
public:
Balrog();
Balrog(int newStrength, int newHit);
int getDamage() const;
};
class Cyberdemon : public Demon {
public:
Cyberdemon();
Cyberdemon(int newStrength, int newHit);
};
int main() {
int damage = 0;
Human aragorn(15, 15);
Cyberdemon doomThrowback(20, 10);
Balrog balor(15, 9);
Elf legolas(12, 12);
cout << "\n\nA cyberdemon appears and attacks Aragorn!";
damage = aragorn.getHitpoints() - doomThrowback.getDamage();
aragorn.setHitpoints(damage);
if (aragorn.getHitpoints() < 0)
cout << "\nAragorn dies!!";
else {
cout << "\n\nAragorn strikes back!";
damage = doomThrowback.getHitpoints() - aragorn.getDamage();
doomThrowback.setHitpoints(damage);
}
cout << "\n\nLegolas looses arrows at the cyberdemon!";
damage = doomThrowback.getHitpoints() - legolas.getDamage();
doomThrowback.setHitpoints(damage);
if (doomThrowback.getHitpoints() < 0)
cout << "\nCyberdemon is defeated!";
cout << "\n\nA cranky Balrog attacks Legolas to avenge his cyber-cousin!";
damage = legolas.getHitpoints() - balor.getDamage();
legolas.setHitpoints(damage);
if (legolas.getHitpoints() < 0)
cout << "\nLegolas falls!";
cout << endl << endl;
system("pause");
return 0;
}
Creature::Creature() {
strength = 0;
hitpoints = 0;
species = "Creature";
}
Creature::Creature(int newStrength, int newHit) {
strength = newStrength;
hitpoints = newHit;
species = "Creature";
}
int Creature::getDamage() const {
int damage;
srand(time(NULL));
damage = (rand() % getStrength()) + 1;
cout << endl << getSpecies() << " attacks for " << damage << " points!";
return damage;
}
int Creature::getStrength() const {
return strength;
}
int Creature::getHitpoints() const {
return hitpoints;
}
string Creature::getSpecies() const {
return species;
}
void Creature::setStrength(int newStrength) {
this->strength = newStrength;
return;
}
void Creature::setHitpoints(int newHit) {
this->hitpoints = newHit;
return;
}
void Creature::setSpecies(string newSpecies) {
this->species = newSpecies;
return;
}
Demon::Demon() : Creature() {
setSpecies("Demon");
}
Demon::Demon(int newStrength, int newHit) : Creature(newStrength, newHit) {
setSpecies("Demon");
}
int Demon::getDamage() const {
int damage;
Creature demon(getStrength(), getHitpoints());
srand(time(NULL));
demon.setSpecies(getSpecies());
damage = demon.getDamage();
if ((rand() % 100) < 5) {
damage = damage + 50;
cout << "\nDemonic attack inflicts 50 " << "additional damage points!";
}
return damage;
}
Elf::Elf() : Creature() {
setSpecies("Elf");
}
Elf::Elf(int newStrength, int newHit) : Creature(newStrength, newHit) {
setSpecies("Elf");
}
int Elf::getDamage() const {
int damage;
Creature elf(getStrength(), getHitpoints());
srand(time(NULL));
elf.setSpecies(getSpecies());
damage = elf.getDamage();
if ((rand() % 10) == 0) {
cout << "\nMagical attack inflicts " << damage << " additional damage points!";
damage = damage * 2;
}
return damage;
}
Human::Human() : Creature() {
setStrength(10);
setHitpoints(10);
setSpecies("Human");
}
Human::Human(int newStrength, int newHit) : Creature(newStrength, newHit) {
setStrength(newStrength);
setHitpoints(newHit);
setSpecies("Human");
}
Balrog::Balrog() : Demon() {
setSpecies("Balrog");
}
Balrog::Balrog(int newStrength, int newHit) : Demon(newStrength, newHit) {
setSpecies("Balrog");
}
int Balrog::getDamage() const {
int damage;
Demon balrog(getStrength(), getHitpoints());
srand(time(NULL));
balrog.setSpecies(getSpecies());
damage = balrog.getDamage();
int damage2 = (rand() % getStrength()) + 1;
cout << "\nBalrog speed attack inflicts " << damage2 << " additional damage points!";
damage = damage + damage2;
return damage;
}
Cyberdemon::Cyberdemon() : Demon() {
setSpecies("Cyberdemon");
}
Cyberdemon::Cyberdemon(int newStrength, int newHit) : Demon(newStrength, newHit) {
setSpecies("Cyberdemon");
}