In this workshop, you are to code a simple hierarchy and define helper functions to support the base and derived classes.

LEARNING OUTCOMES

Upon successful completion of this workshop, you will have demonstrated the abilities to:

  • inherit a derived class from a base class
  • shadow a base class member function with a derived class member function
  • access a shadowed member function that is defined in a base class
  • define a non-friend helper function that supports a class
  • implement friendship between a helper function and the class it supports
  • describe what you have learned in completing this workshop

IN-LAB

Design a base class named Hero, in namespace sict. This class holds information about a fictional hero character. Place your class definition in a header file named Hero.h and your function definitions in an implementation file named Hero.cpp. Include in your design all of the statements necessary to compile and to run your code successfully using a standard C++ compiler.

The model for battles between Heroes is simple. Each Hero has a non-negative integer health number. A Hero is not alive if their health is 0. During a battle Heroes attack one another. Each Hero has their own specific attack strength. Each attack inflicts damage on the attacked Hero. The inflicted damage is subtracted from the attacked Hero's health. The winner of the battle is the Hero who remains alive when the other Hero has died. A Hero is alive as long as their health number is positive-valued. A battle ends in a draw after max_rounds rounds.

Initialize max_rounds to 100.

A Hero object contains the following data:

  • The name of the Hero - up to 40 characters (excluding the null byte)
  • The health of the Hero - a positive-valued integer
  • The attack strength of the Hero - a positive-valued integer

Upon instantiation, a Hero object receives no information or information on all three values. If the information received is valid, the object accepts them. Otherwise, the object assumes a safe empty state.

Your design includes the following member functions:

void operator-=(int attack): an overloaded operator that receives an attack strength and, if that strength is positive-valued, deducts that strength from the current object's health. If the attack strength received is not positive-valued, this operator does nothing. If the deduction drops the current objects health below 0, this operator resets its health to 0.

bool isAlive() const: a query that returns true if the current object is healthy and false otherwise.

int attackStrength() const: a query that returns the attack strength of the current object. If the object is in a safe empty state, this function returns 0.

Your design includes two helper operators, which support your class:

ostream& operator<<(ostream& os, const Hero& hero): a friend that inserts the name of hero into stream os and returns a reference to that stream. If hero is empty, this function displays the message:

No hero

const Hero& operator*(const Hero& first, const Hero& second): a non-friend that returns an unmodifiable reference to the winner of the battle between the Heroes after max_rounds rounds. This function displays the names of the battle participants as shown in the sample output below, makes local copies of the participants, determines the damage that each inflicts on the other in a single attack and battles until either one of the participants dies or the maximum number of rounds is reached. In each round, this function deducts the damage inflicted on one Hero by the other Hero. Finally, this function displays the name of the winner. In the case of a draw, this function assumes arbitrarily that the left operand (first) has won. This function returns a reference to the winner object.

Using the sample implementation of the w7_in_lab.cpp main module listed below, test your code and make sure that it works. The expected output from your program is listed below this source code. The output of your program should match exactly the expected one.

IN-LAB MAIN MODULE

#include < iostream>
#include "Hero.h"

using namespace std;
using namespace sict;

int main()
{

cout << "Greek Heroes";
Hero hercules ("Hercules", 32, 4);
Hero theseus ("Theseus", 14, 5);
Hero oddyseus ("Odysseus", 15, 3);
Hero ajax ("Ajax", 17, 5);
Hero achilles ("Achilles", 20, 6);
Hero hector ("Hector", 30, 5);
Hero atalanta ("Atalanta", 10, 3);
Hero hippolyta ("Hippolyta", 10, 2);

cout << endl << "Quarter Finals" << endl;
const Hero& greek_winner1 = achilles * hector;
const Hero& greek_winner2 = hercules * theseus;
const Hero& greek_winner3 = oddyseus * ajax;
const Hero& greek_winner4 = atalanta * hippolyta;

cout << endl << "Semi Finals" << endl;
const Hero& greek_winner_semifinal1 = greek_winner1 * greek_winner2;
const Hero& greek_winner_semifinal2 = greek_winner3 * greek_winner4;

cout << endl << "Finals" << endl;
greek_winner_semifinal1 * greek_winner_semifinal2;

return 0;
}

IN-LAB EXPECTED OUTPUT

Greek Heroes
Quarter Finals
Ancient Battle! Achilles vs Hector : Winner is Hector in 4 rounds.
Ancient Battle! Hercules vs Theseus : Winner is Hercules in 4 rounds.
Ancient Battle! Odysseus vs Ajax : Winner is Ajax in 3 rounds.
Ancient Battle! Atalanta vs Hippolyta : Winner is Atalanta in 4 rounds.

Semi Finals
Ancient Battle! Hector vs Hercules : Winner is Hector in 7 rounds.
Ancient Battle! Ajax vs Atalanta : Winner is Ajax in 2 rounds.

Finals
Ancient Battle! Hector vs Ajax : Winner is Hector in 4 rounds.

AT-HOME

Derive a class named SuperHero from the Hero class that you coded for the in-lab section. Include in your design all of the statements and keywords necessary to compile and to run your code successfully using a standard C++ compiler.

Super Heroes behave like Heroes, except that Super Heroes have Super Powers! A SuperHero has a regular normal attack strength, and health, but can also use their super power to attack with a bonus, and to defend themselves but only against another SuperHero. When a SuperHero fights against a Hero, the SuperHero does not use its super power, but only uses its regular Hero attack strength.

Upon instantiation, a SuperHero object may receive no information or the following five values:

  • The address of a C-style string containing the name of the SuperHero,
  • The health of the SuperHero,
  • The attack strength of the SuperHero in attacks on a Hero,
  • The super power attack bonus of the SuperHero,
  • The defend strength of the SuperHero.

The model for a SuperHero battle is the same as the model for a Hero battle, but the damage in any single round is calculated differently. When a SuperHero attacks another SuperHero, the attack strength of the attacking SuperHero is its attack strength plus its bonus attack strength. Moreover, when a SuperHero is attacked by another SuperHero, the damage to the attacked SuperHero is the attack strength of the attacking SuperHero minus the defend strength of the attacked SuperHero.

Damage(A) = (Attack of B + AttackBonus of B) – DefendStrength of A
Damage(B) = (Attack of A + AttackBonus of A) – DefendStrength of B

Your SuperHero class includes the two constructors described above and the following member functions:

int attackStrength() const: a query that returns the attack strength of the current object including its super power bonus. If the object is in a safe empty state, this function returns 0.

int defend() const: a query that returns the defend strength of the current object. If the object is in a safe empty state, this function returns 0.

Your design includes a helper operator, which supports your class:

const SuperHero& operator*(const SuperHero& first, const SuperHero& second): a non-friend that returns an unmodifiable reference to the winner of the battle between the SuperHeroes after max_rounds rounds. This function displays the names of the battle participants as shown in the sample output below, makes local copies of the participants, determines the damage that each inflicts on the other in a single attack and battles until either one of the participants dies or the maximum number of rounds is reached. In each round, this function deducts the damage inflicted on a SuperHero by the other SuperHero. Finally, this function displays the name of the winner. In the case of a draw, this function assumes arbitrarily that the left operand (first) has won. This function returns a reference to the winner object.

The following program (w7_at_home.cpp) uses your SuperHero and Hero classes and produces the output listed below.

#include < iostream>
#include "Hero.h"
#include "SuperHero.h"

using namespace std;
using namespace sict;

void line(int width) {
cout.width(width - 1);
cout.fill('-');
cout << '-';
cout.fill(' ');
}

int main() {
line(60);

cout << endl << "Greek Heroes";
Hero hercules ("Hercules", 32, 4);
Hero theseus ("Theseus", 14, 5);
Hero oddyseus ("Odysseus", 15, 3);
Hero ajax ("Ajax", 17, 5);
Hero achilles ("Achilles", 20, 6);
Hero hector ("Hector", 30, 5);
Hero atalanta ("Atalanta", 10, 3);
Hero hippolyta ("Hippolyta", 10, 2);

cout << endl << "Quarter Finals" << endl;
const Hero& greek_winner1 = achilles * hector;
const Hero& greek_winner2 = hercules * theseus;
const Hero& greek_winner3 = oddyseus * ajax;
const Hero& greek_winner4 = atalanta * hippolyta;

cout << endl << "Semi Finals" << endl;
const Hero& greek_winner_semifinal1 = greek_winner1 * greek_winner2;
const Hero& greek_winner_semifinal2 = greek_winner3 * greek_winner4;

cout << endl << "Finals" << endl;
const Hero& greek_final = greek_winner_semifinal1 * greek_winner_semifinal2;

line(60);
cout << endl << "Comic book SuperHeros";

SuperHero superman ("Superman", 50, 9, 1, 9) ;
SuperHero hulk ("The_Hulk", 70, 6, 14, 3) ;
SuperHero wonderwoman ("WonderWoman", 80, 5, 10, 10) ;
SuperHero raven ("Raven", 30, 10, 2, 5) ;

cout << endl << "Semi Finals" << endl;
const SuperHero& comic_winner1 = superman * hulk;
const SuperHero& comic_winner2 = wonderwoman * raven;

cout << endl << "Finals" << endl;
const SuperHero& comic_final = comic_winner1 * comic_winner2;

line(60);
cout << endl << "Best Greeks Hero vs Best Comic Book SuperHero" << endl;
greek_final * comic_final;
}
-----------------------------------------------------------
Greek Heroes
Quarter Finals
Ancient Battle! Achilles vs Hector : Winner is Hector in 4 rounds.
Ancient Battle! Hercules vs Theseus : Winner is Hercules in 4 rounds.
Ancient Battle! Odysseus vs Ajax : Winner is Ajax in 3 rounds.
Ancient Battle! Atalanta vs Hippolyta : Winner is Atalanta in 4 rounds.

Semi Finals
Ancient Battle! Hector vs Hercules : Winner is Hector in 7 rounds.
Ancient Battle! Ajax vs Atalanta : Winner is Ajax in 2 rounds.

Finals
Ancient Battle! Hector vs Ajax : Winner is Hector in 4 rounds.
-----------------------------------------------------------
Comic book SuperHeros
Semi Finals
Super Fight! Superman vs The_Hulk : Winner is The_Hulk in 5 rounds.
Super Fight! WonderWoman vs Raven : Winner is WonderWoman in 3 rounds.

Finals
Super Fight! The_Hulk vs WonderWoman : Winner is WonderWoman in 6 rounds.
-----------------------------------------------------------
Best Greeks Hero vs Best Comic Book SuperHero
Ancient Battle! Hector vs WonderWoman : Winner is WonderWoman in 6 rounds.
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.