C++ - Create a simple class hierarchy as the basis for a fantasy combat game. Th
ID: 3668532 • Letter: C
Question
C++ - Create a simple class hierarchy as the basis for a fantasy combat game. The ‘universe’ contains Goblins, Barbarians, Reptile People, Blue Men and others. Each will have characteristics for attack, defense, armor, and strength points.
3d6 is rolling three 6-sided dice. 2d10 is rolling two 10-sided dice.
*Glare- If a Medusa rolls a 12 in attack then the target has looked her in the eyes and is turned to stone. The Medusa wins!
*Charm- Vampires can charm an opponent into not attacking. For a given attack there is a 50% chance that their opponent does not actually attack them.
*Mob- The Blue Men are actually a swarm of small individuals. For every 4 points of damage (round down) they lose on defense die. For example, when they reach strength of 8 they only have 2d6 for defense.
*Hogwarts- If Harry dies (i.e. strength >=0) he immediately recovers. His total strength becomes 20. If he were to die again then he’s dead.
To resolve an attack you will need to generate 2 dice rolls. The attacker rolls the appropriate number and type of dice under Attack. The defender rolls the appropriate number and type of dice under Defense. You subtract the Defense roll from the Attack roll. That is the damage. Each class only has its own information or data. When O1 is fighting O2 your program should call O1’s attack function. It will return the damage inflicted. Then O2’s defense function will take the damage inflicted, then roll the specified dice and subtract the points for the defense. To apply the damage you subtract the Armor value. The result is then subtracted from the Strength Points. That value becomes the new Strength Points for the next round. If Strength Points goes to 0 or less then the character is out of the combat. If it receives 8 points of damage and rolls3 for it’s defense and has an armor of 3 it would take 8 subtract 3 and then 3 for the armor to receive 2 points of damage.
Create a Creature class. Then you will have a subclass for each of these characters. Note that the Creature class will be an abstract class. You will never instantiate one. For our purposes right now each subclass will vary only in the values in the table. Since each starts with the same data elements you will only need one constructor. It is part of your design task to determine what functions you will need. The only value that can change is the Strength Points.
-----------------------------------------------------
I am not sure if I am on the right track or not...
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Creature{
public:
Creature(int a, int s)
{
armor = a;
strength = s;
}
virtual int attack() = 0;
virtual int defense() = 0;
int armor;
int strength;
void setArmor(int arm)
{
armorVal = arm;
}
void setStrength(int str)
{
strengthVal = str;
}
};
class Combat: public Creature
{
public:
int getArmor()
{
return armor;
}
int getStrength()
{
return strength;
}
};
class Medusa:public Creature
{
armor = 3;
strength = 8;
virtual int attack()
{
int sum = 0;
for(int i = 0; i < 2; i++)
{
sum += rand() % 6 + 1;
}
// if(sum == 12) she wins
}
virtual int defense()
{
int sum = rand() % 6 + 1;
}
};
class Barbarian:public Creature
{
armor = 0;
strength = 12;
virtual int attack()
{
int sum = 0;
for(int i = 0; i < 2; i++)
{
sum += rand() % 6 + 1;
}
}
virtual int defense()
{
int sum = 0;
for(int i = 0; i < 2; i++)
{
sum += rand() % 6 + 1;
}
}
};
class Vampire:public Creature
{
armor = 1;
strength = 18;
virtual int attack()
{
int sum + rand() % 12 + 1
}
virtual int defense()
{
int sum = rand() % 6 + 1;
}
};
class BlueMen:public Creature
{
armor = 3;
strength = 12;
virtual int attack()
{
int sum = 0;
for(int i = 0; i < 2; i++)
{
sum += rand() % 10 + 1;
}
}
virtual int defense()
{
int sum = 0;
for(int i = 0; i < 3; i++)
{
sum += rand() % 6 + 1;
}
}
};
class HarryPotter:public Creature
{
armor = 0;
strength = 10;
virtual int attack()
{
int sum = 0;
for(int i = 0; i < 2; i++)
{
sum += rand() % 6 + 1;
}
}
virtual int defense()
{
int sum = 0;
for(int i = 0; i < 2; i++){
sum += rand() % 6 + 1;
}
}
};
Explanation / Answer
main.cpp
#include "creature.h"
#include "goblin.h"
#include "barbarian.h"
#include "reptile.h"
#include "shadow.h"
#include "blueMen.h"
#include "dice.h"
#include <iostream>
#include <string>
using namespace std;
void fight(Creature* player1, Creature* player2) {
cout << "----------------------------------------------" << endl;
cout << player1->getType() << " VS. " << player2->getType() << "!!!!" << endl;
cout << "----------------------------------------------" << endl;
bool gameOver = false;
while(!gameOver) {
player1->attack(player2);
player2->attack(player1);
cout << endl << player1->getType() << " strength: " << player1->getStrength() << endl;
cout << player2->getType() << " strength: " << player2->getStrength() << " ";
if (player1->isDead()) {
cout << player1->getType() << " is dead! " << endl;
gameOver = true;
}
if (player2->isDead()) {
cout << player2->getType() << " is dead! " << endl;
gameOver = true;
}
}
cout << " ";
delete player1;
delete player2;
}
int main() {
fight(new Barbarian, new Barbarian);
fight(new Barbarian, new Shadow);
fight(new Barbarian, new Goblin);
fight(new Barbarian, new BlueMen);
fight(new Barbarian, new Reptile);
fight(new Shadow, new Shadow);
fight(new Shadow, new Goblin);
fight(new Shadow, new BlueMen);
fight(new Shadow, new Reptile);
fight(new Goblin, new Goblin);
fight(new Goblin, new BlueMen);
fight(new Goblin, new Reptile);
fight(new BlueMen, new BlueMen);
fight(new BlueMen, new Reptile);
fight(new Reptile, new Reptile);
return 0;
}
barbarian.cpp
#include "barbarian.h"
#include "creature.h"
#include "dice.h"
#include <iostream>
using namespace std;
Barbarian::Barbarian() {
type = "Barbarian";
strength = 12;
armor = 0;
multiplier = 1;
attack1 = Dice(6);
attack2 = Dice(6);
defense1 = Dice(6);
defense2 = Dice(6);
}
/*the attack amount for a player. It returns the attack as an int.*/
int Barbarian::rollAttackDice(){
return Dice::rollTwoDice(attack1, attack2);
}
/*It returns the defense as an int.*/
int Barbarian::rollDefenseDice(){
return Dice::rollTwoDice(defense1, defense2);
}
barbarian.h
#ifndef BARBARIAN
#define BARBARIAN
#include "creature.h"
#include "dice.h"
#include <iostream>
using namespace std;
class Barbarian : public Creature {
public:
Barbarian();
Dice attack1;
Dice attack2;
Dice defense1;
Dice defense2;
virtual int rollAttackDice();
virtual int rollDefenseDice();
};
#endif
blueMen.cpp
#include "blueMen.h"
#include "dice.h"
#include <iostream>
using namespace std;
BlueMen::BlueMen() {
type = "Blue Man";
strength = 12;
armor = 3;
multiplier = 1;
attack1 = Dice(10);
attack2 = Dice(10);
defense1 = Dice(6);
defense2 = Dice(6);
defense3 = Dice(6);
}
/* returns the attack as an int.*/
int BlueMen::rollAttackDice(){
return Dice::rollTwoDice(attack1, attack2);
}
/*returns the defense as an int.*/
int BlueMen::rollDefenseDice(){
return Dice::rollThreeDice(defense1, defense2, defense3);
}
blueMen.h
#ifndef BlUEMEN
#define BlUEMEN
#include <iostream>
#include "creature.h"
#include "dice.h"
using namespace std;
class BlueMen : public Creature {
public:
Dice attack1;
Dice attack2;
Dice defense1;
Dice defense2;
Dice defense3;
BlueMen();
virtual int rollAttackDice();
virtual int rollDefenseDice();
};
#endif
creature.cpp
#include "creature.h"
#include "dice.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
/* setter function for multiplier.*/
void Creature::setMultiplier(double multiplier) {
this->multiplier = multiplier;
}
/*getter function for multiplier*/
double Creature::getMultiplier() {
return multiplier;
}
/*setter function for armor*/
void Creature::setArmor(int armor) {
this->armor = armor;
}
/** getter function for armor**/
int Creature::getArmor() {
return armor;
}
/*setter function for strength.*/
void Creature::setStrength(double strength) {
this->strength = strength;
}
/*getter function for strength**/
double Creature::getStrength() {
return strength;
}
/*getter function for type.*/
string Creature::getType() {
return type;
}
/**determines the damage of an attack by calling rollAttackDice().*/
void Creature::attack(Creature* opponent) {
string multMsg = "";
int damage = rollAttackDice();
double totalDamage = damage * multiplier;
if (multiplier < 1)
{
stringstream ss;
ss << totalDamage;
multMsg = "/2 = " + ss.str();
}
cout << this->type << " attacks " << opponent->type;
cout << " (" << damage << multMsg << ") " << endl;
opponent->applyDamage(totalDamage);
}
/**determines the defense of a player by calling rollDefenseDice()**/
int Creature::defense() {
return rollDefenseDice();
}
/**amount of damage to apply to the player*/
void Creature::applyDamage(double damage) {
int def = defense();
double totalDamage = (damage - armor) - def;
if (totalDamage < 0)
{
totalDamage = 0;
}
double newStrength = strength - totalDamage;
strength = newStrength;
cout << this->type << " defends " << " (" << def << ") + armor (" << armor << ")"<< endl;
cout << this->type << " takes damage " << " (" << totalDamage << ") " << endl;
}
/**check if a player is dead and retun a bool accordingly.*/
bool Creature::isDead() {
bool dead = this->strength <= 0;
return dead;
}
creature.h
#ifndef CREATURE
#define CREATURE
#include "dice.h"
#include <iostream>
#include <string>
using namespace std;
class Creature {
protected:
string type;
double strength;
int armor;
double multiplier;
virtual int rollAttackDice() = 0;
virtual int rollDefenseDice() = 0;
public:
void setMultiplier(double multiplier);
string getType();
double getMultiplier();
void setArmor(int Armor);
int getArmor();
void setStrength(double strength);
double getStrength();
virtual ~Creature(){};
virtual void attack(Creature* opponent);
virtual int defense();
virtual void applyDamage(double damage);
bool isDead();
};
#endif
dice.cpp
#include "dice.h"
#include <iostream>
using namespace std;
/*dice constructor*/
Dice::Dice() {
numSides = 6;
srand(time(NULL)); // Seeds random number generator
}
/* constructor, with a parameter for the number of sides*/
Dice::Dice(int numSides) {
this->numSides = numSides;
srand(time(NULL)); // Seeds random number generator
}
/*function will roll a single dice.*/
int Dice::rollDice() {
return (rand() % numSides) + 1;
}
/*****************************************************
** Function: rollTwoDice()
** Description: This function will roll two dice and
return the sum.
** Parameters: takes two dice objects
** Pre-Conditions: None
** Post-Conditions:returns sum of two dice rolls
*******************************************************/
int Dice::rollTwoDice(Dice& die1, Dice& die2) {
return die1.rollDice() + die2.rollDice();
}
/** function will roll three dice and return the sum.*/
int Dice::rollThreeDice(Dice& die1, Dice& die2, Dice& die3) {
return die1.rollDice() + die2.rollDice() + die3.rollDice();
}
dice.h
#ifndef DICE
#define DICE
#include <iostream>
using namespace std;
class Dice
{
protected:
int numSides;
public:
Dice();
Dice(int numSides);
int rollDice();
static int rollTwoDice(Dice& die1, Dice& die2);
static int rollThreeDice(Dice& die1, Dice& die2, Dice& die3);
};
#endif
goblin.cpp
#include "goblin.h"
#include "dice.h"
#include <iostream>
using namespace std;
Goblin::Goblin() {
type = "Goblin";
strength = 8;
armor = 3;
multiplier = 1;
attack1 = Dice(6);
attack2 = Dice(6);
defense1 = Dice(6);
}
/**determines the damage of an attack by calling rollAttackDice(). */
void Goblin::attack(Creature* opponent) {
double damage = rollAttackDice();
cout << this->type << " attacks " << opponent->getType();
cout << " (" << damage << ") " << endl;
if (opponent->getType() != "Golbin" && damage == 12) {
cout << this->type << " has stuck the Achilles!" << endl;
double prevMultiplier = opponent->getMultiplier();
opponent->setMultiplier(prevMultiplier/2);
}
opponent->applyDamage(damage);
}
/**determines the attack amount for a player.*/
int Goblin::rollAttackDice(){
return Dice::rollTwoDice(attack1, attack2);
}
/*the defense amount for a player.**/
int Goblin::rollDefenseDice(){
return defense1.rollDice();
}
goblin.h
#ifndef GOBLIN
#define GOBLIN
#include "creature.h"
#include "dice.h"
#include <iostream>
using namespace std;
class Goblin: public Creature {
public:
Goblin();
Dice attack1;
Dice attack2;
Dice defense1;
virtual void attack(Creature* opponent);
virtual int rollAttackDice();
virtual int rollDefenseDice();
};
#endif
reptile.cpp
#include "reptile.h"
#include "dice.h"
#include <iostream>
using namespace std;
Reptile::Reptile() {
type = "Reptile";
strength = 18;
armor = 7;
multiplier = 1;
attack1 = Dice(6);
attack2 = Dice(6);
attack3 = Dice(6);
defense1 = Dice(6);
}
/**the attack amount for a player.**/
int Reptile::rollAttackDice() {
return Dice::rollThreeDice(attack1, attack2, attack3);
}
/*the defense amount for a player. */
int Reptile::rollDefenseDice() {
return defense1.rollDice();
}
reptile.h
#ifndef REPTILE
#define REPTILE
#include "creature.h"
#include "dice.h"
#include <iostream>
using namespace std;
class Reptile : public Creature {
public:
Reptile();
Dice attack1;
Dice attack2;
Dice attack3;
Dice defense1;
virtual int rollAttackDice();
virtual int rollDefenseDice();
};
#endif
shadow.cpp
#include "shadow.h"
#include "dice.h"
#include <iostream>
using namespace std;
Shadow::Shadow() {
type = "Shadow";
strength = 12;
armor = 0;
multiplier = 1;
attack1 = Dice(10);
attack2 = Dice(10);
defense1 = Dice(6);
}
/***the attack amount for a player. */
int Shadow::rollAttackDice() {
return Dice::rollTwoDice(attack1, attack2);
}
/*the defense amount for a player. */
int Shadow::rollDefenseDice() {
return defense1.rollDice();
}
/*the amount of damage for a player.*/
void Shadow::applyDamage(double damage) {
Dice escapedDamage(2);
int def = defense();
double totalDamage = (damage - armor) - def;
if (escapedDamage.rollDice() % 2 == 1) {
cout << this->type << " takes no damage " << endl;
return;
}
else {
if (totalDamage < 0)
{
totalDamage = 0;
}
cout << this->type << "defends " << " (" << def << ") " << endl;
cout << this->type << "defends " << " (" << def << ") + armor (" << armor << ")"<< endl;
int newStrength = strength - totalDamage;
strength = newStrength;
}
}
shadow.h
#ifndef SHADOW
#define SHADOW
#include "creature.h"
#include "dice.h"
#include <iostream>
using namespace std;
class Shadow : public Creature {
public:
Shadow();
Dice attack1;
Dice attack2;
Dice defense1;
virtual int rollAttackDice();
virtual int rollDefenseDice();
virtual void applyDamage(double damage);
};
#endif
sample output
Reptile attacks Reptile (17)
Reptile defends (3) + armor (7)
Reptile takes damage (7)
Reptile attacks Reptile (12)
Reptile defends (2) + armor (7)
Reptile takes damage (3)
Reptile strength: 11
Reptile strength: 9
Reptile attacks Reptile (6)
Reptile defends (6) + armor (7)
Reptile takes damage (0)
Reptile attacks Reptile (9)
Reptile attacks Reptile (9)
Reptile defends (6) + armor (7)
Reptile takes damage (0)
Reptile strength: 11
Reptile strength: 9
Reptile attacks Reptile (14)
Reptile defends (2) + armor (7)
Reptile takes damage (5)
Reptile attacks Reptile (15)
Reptile defends (1) + armor (7)
Reptile takes damage (7)
Reptile strength: 4
Reptile attacks Reptile (10)
Reptile defends (3) + armor (7)
Reptile takes damage (0)
Reptile attacks Reptile (5)
Reptile defends (5) + armor (7)
Reptile takes damage (0)
Reptile strength: 4
Reptile strength: 4
Reptile attacks Reptile (6)
Reptile defends (4) + armor (7)
Reptile takes damage (0)
Reptile attacks Reptile (12)
Reptile defends (4) + armor (7)
Reptile takes damage (1)
Reptile strength: 3
Reptile strength: 4
Reptile attacks Reptile (8)
Reptile defends (1) + armor (7)
Reptile takes damage (0)
Reptile attacks Reptile (14)
Reptile defends (5) + armor
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.