Question

In: Computer Science

THIS IS A C++ QUESTION(SOME OTHER ASSIGNMENTS ARE DISPLAYED TO GIVE BACKGROUND INFO ON THIS QUESTION,...

THIS IS A C++ QUESTION(SOME OTHER ASSIGNMENTS ARE DISPLAYED TO GIVE BACKGROUND INFO ON THIS QUESTION, ONLY THIS QUESTION SHOULD BE SOLVED):

Focus

  • Dynamic memory

Update

  • Do NOT make the Noble class a friend of the Warrior class.
  • Do NOT put a pointer in the Warrior class to the Noble class.

Problem:

Building on previous assignments, we will be reading a file of commands to create Nobles and Warriors, and sending them off to battle.

Previous Assignments(As Background info):

1) We will model a game of medieval times. Our world is filled with warriors. Naturally what warriors like to do is fight. To the death. So we happily let them.

Each warrior starts out with a name and a certain amount of strength. Each time he fights, he loses some strength. (He gets to keep his name.) If his opponent is stronger than he is, then he loses all of his strength, in which case he is dead, or at the very least pretty useless as a fighter. Otherwise he loses as much strength as his opponent had. Of course, if he and his opponent had the same strength then they are both losers.

Even losers are allowed to pick a fight. It doesn't require having any strength in order to do battle with someone else. Not that you stand much of a chance of winning anything, but perhaps it's worth getting beaten (again) just to have those 15 seconds of fame.

Your program will read in a file of commands. There are three types of commands:

  • Warrior creates a new warrior with the specified name and strength.
  • Battle causes a battle to occur between two warriors.
  • Status lists all warriors, alive or dead, and their strengths

2)

We will expand our Warrior a little. Each Warrior will have a weapon. He is "born" with it, i.e. the weapon is created together with the warrior. It can only be accessed by him. It provides him with his strength. In battle, weapons lose their edge and weaken. When a Warrior's weapon loses all of its strength, the Warrior himself dies.

Implementation

  • Remember that we are using data hiding. Therefore, every field, aka member variable, must be private.
  • What are the types of things in the problem? We will need a class for each type.
  • What do the things / types do? These "behaviors" should be represented as methods.
  • Weapons have both a name and a strength. The weapon is created together with the Warrior and cannot be accessed by anyone else.
  • Note that the input file changed a little, compared to the previous assignment. When a Warrior is created, instead of simply specifying his name and strength, the Warrior command specifies the Warrior's name as well as his Weapon's name and its strength.
  • The Status report will is also modified to show the name of the Warrior's Weapon.
  • No one can access a warrior's weapon except the warrior himself. But the weapon is what actually holds the warrior's strength. How does this effect the programming? Any time the code needs to know or change the warrior's strength, the warrior then "asks" the weapon what the strength is or tells the weapon that the strength needs to be changed. This represents the idea of delegation. We will see this concept frequently, where one object requests that another object do some task.
  • It is in fact unnecessary for any code other than a Warrior to even know about the Weapon. We will enforce this by nesting the definition of the Weapon class inside the Warrior class. To make sure that no code other than Warrior's makes use of Weapon, we need to make the class private.
  • The name of the input file will be "warriors.txt".
  • One last implementation detail. to display the information about an object, whether it is a warrior or a weapon, we will use that object's output operator.

3)

We will [continue to] model a game of medieval times. Our world is filled with not only warriors but also nobles. Nobles don't have much to do except do battle with each other. (We'll leave the feasting and other entertainments for add-ons.) Warriors don't have much to do except hire out to a noble and fight in his behalf. Of course the nobles are pretty wimpy themselves and will lose if they don't have warriors to defend them. How does all this work?

  • Warriors start out with a specified strength.
  • A battle between nobles is won by the noble who commands the stronger army.
  • The army's strength is simply the combined strengths of all its warriors.
  • A battle is to the death. The losing noble dies as does his warriors.
  • The winner does not usually walk away unscarred. All his men lose a portion of their strength equal to the ratio of the enemy army's combined strenth to their army's. If the losing army had a combined strength that was 1/4 the size of the winning army's, then each soldier in the winning army will have their own strength reduced by 1/4.

Hiring and Firing

  • Warriors are hired and fired by Nobles. Lack of adequate labor laws, have left the Warriors without the ability to quit, nor even to have a say on whether or not a Noble can hire them.
  • However it is possible that an attempt to hire or fire may fail. Naturally the methods should not "fail silently". Instead, they will return true or false depending on whether they succeed or not.
  • A Warrior can only be employed by one Noble at a time and cannot be hired away if he is already employed.
  • As noted below, Nobles who are dead can neither hire nor fire anyone. (Note this will implicitly prevent dead Warriors from being hired.)
  • When a warrior is fired, he is no longer part of the army of the Noble that hired him. He is then free to be hired by another Noble.
    • How do you remove something from a vector.
    • While there are techniques that make use of iterators, we have not yet discussed iterators so you will not use them here. (As a heads up, if you see a technique that requires you to call a vector's begin() method, that is using iterators. Don't use it.)
    • While it may seem a slight burden, certainly it does not require more than a simple loop to remove an item from a vector. No do not do something silly like create a whole new vector.
    • Soon we will cover iterators and then you will be freed from these constraints. Patience, please.

Death

It's a sad topic, but one we do have to address.

  • People die when they lose a battle, whether they are a Nobles or Warriors.
  • Nobles who are dead are in no position to hire or fire anyone. Any attempt by a dead Lord to hire someone will simply fail and the Warrior will remain unhired.
  • However curiously, as has been seen before, Nobles can declare battle even though they are dead.
  • Note that when a Noble is created he does not have any strength. At the same time he is obviously alive. So lack of strength and being dead are clearly not equivalent.

A test program and output are attached. Note that the output shown is what you are expected to generate. Pardon us, we don't like limiting your creativity, but having your output consistent with ours makes the first step of grading a bit easier. And also helps you to be more confident that your code works.

Key differences:

  • Each time a warrior or a noble is defined, we will create it on the heap.
  • We will keep track of the nobles in a vector of pointers to nobles.
  • We will keep track of all warriors using a vector of pointers to warriors.

Commands

  • Noble. Create a Noble on the heap.
  • Warrior. Create a Warrior on the heap.
  • Hire. Call the Noble's hire method.
  • Fire. Call the Noble's fire method.
  • Battle. Call the Noble's battle method.
  • Status. The status command shows the nobles, together with their armies, as we did previously. In addition, it will show separately the warriors who do not currentle have a employer
  • Clear. Clear out all the nobles and warriors that were created.

Our application is going to rely on each Noble having a unique name and each Warrior having a unique name. Otherwise, how would we be sure who we were hiring (or firing). Note that this is not a requirement of the Noble and Warrior classes themselves, just of this particular use of them, i.e. our application.

Whenever you are displaying a Noble or a Warrior, you will use the output operator for the class.

Handle errors!

Previously we promised that all of the commands we gave you the input would be valid. Now we would like you to take some responsibility for checking the input. First, we still guarantee that the format of the file will be correct. That means that the Warrior command will always have a name and a strength. The Battle command will always have two names. The Status command will not have any other information on it than just the word Status.

However, you will need to detect and report any issues indicating inconsistencies, such as:

  • Noble command: if a Noble with a given name already exists.
  • Warrior command:if a Warrior with a given name already exists.
  • Hire command: If a Noble tries to hire a Warrior and either of them do not exist.
  • Fire command: If a Noble tries to fire a Warrior and either the Noble does not exist or does not have the Warrior by that name in this army.
  • Battle command: If a Noble initiates a battle with another Noble, but one or the other does not exist

We have not specified the format of these error messages, so we'll leave that up to you. (You get to be creative!)

Input:

"Noble King_Arthur
Noble Lancelot_du_Lac
Noble Jim
Noble Linus_Torvalds
Noble Bill_Gates
Warrior Tarzan 10
Warrior Merlin 15
Warrior Conan 12
Warrior Spock 15
Warrior Xena 20
Warrior Hulk 8
Warrior Hercules 3
Hire Jim Spock
Hire Lancelot_du_Lac Conan
Hire King_Arthur Merlin
Hire Lancelot_du_Lac Hercules
Hire Linus_Torvalds Xena
Hire Bill_Gates Hulk
Hire King_Arthur Tarzan
Status
Fire King_Arthur Tarzan
Status
Battle King_Arthur Lancelot_du_Lac
Battle Jim Lancelot_du_Lac
Battle Linus_Torvalds Bill_Gates
Battle Bill_Gates Lancelot_du_Lac
Status
Clear
Status"

Output:

"Status
======
Nobles:
King_Arthur has an army of 2
        Merlin: 15
        Tarzan: 10
Lancelot_du_Lac has an army of 2
        Conan: 12
        Hercules: 3
Jim has an army of 1
        Spock: 15
Linus_Torvalds has an army of 1
        Xena: 20
Bill_Gates has an army of 1
        Hulk: 8
Unemployed Warriors:
NONE
You don't work for me anymore Tarzan! -- King_Arthur.
Status
======
Nobles:
King_Arthur has an army of 1
        Merlin: 15
Lancelot_du_Lac has an army of 2
        Conan: 12
        Hercules: 3
Jim has an army of 1
        Spock: 15
Linus_Torvalds has an army of 1
        Xena: 20
Bill_Gates has an army of 1
        Hulk: 8
Unemployed Warriors:
Tarzan: 10
King_Arthur battles Lancelot_du_Lac
Mutual Annihalation: King_Arthur and Lancelot_du_Lac die at each other's hands
Jim battles Lancelot_du_Lac
He's dead, Jim
Linus_Torvalds battles Bill_Gates
Linus_Torvalds defeats Bill_Gates
Bill_Gates battles Lancelot_du_Lac
Oh, NO!  They're both dead!  Yuck!
Status
======
Nobles:
King_Arthur has an army of 1
        Merlin: 0
Lancelot_du_Lac has an army of 2
        Conan: 0
        Hercules: 0
Jim has an army of 1
        Spock: 15
Linus_Torvalds has an army of 1
        Xena: 12
Bill_Gates has an army of 1
        Hulk: 0
Unemployed Warriors:
Tarzan: 10
Status
======
Nobles:
NONE
Unemployed Warriors:
NONE"

Solutions

Expert Solution

program code to copy

main.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Noble;
class Warrior;

class Warrior 
{
        //display the warrior's name and strength
        friend ostream& operator<<(ostream& os, const Warrior& war) 
        {
                os << "    " << war.name << ": " << war.strength;
                return os;
        }
public:
        Warrior(const string& name, int strength) :
                name(name), strength(strength)
        {}
        const Noble* getmaster() const { return master; }
        const string& getname() const { return name; }
        const int getstrength() const { return strength; }
        void setmaster(Noble* themaster) { master = themaster; }
        void setstrength(int stren) { strength = stren; }
private:
        int strength;
        string name;
        Noble* master = nullptr;

};
class Noble 
{
        //display the noble and warriors' name and strength
        friend ostream& operator<<(ostream& os, const Noble& nob) 
        {
                os << nob.name << " has an army of " << nob.warriors.size() << endl;
                for (size_t i = 0; i < nob.warriors.size(); ++i) 
                {
                        os << *nob.warriors[i] << endl;
                }
                return os;
        }
public:
        Noble(const string& name) :
                name(name)
        {}
        const string& getname() const { return name; }
        void hire(Warrior* war) 
        {
                if (war->getmaster() == nullptr) 
                {//only hire no-master warrior
                        warriors.push_back(war);
                        war->setmaster(this);
                        totalstrength += war->getstrength();
                }
        }
        void fire(Warrior* war) 
        {
                if (war->getmaster() == this) 
                {
                        for (size_t i = 0; i < warriors.size(); ++i) 
                        {
                                if (warriors[i] == war) 
                                {
                                        while (i < warriors.size() - 1) 
                                        {
                                                swap(warriors[i], warriors[i + 1]);//make fired warriors to the end of vector
                                        }
                                        warriors.pop_back();
                                        break;
                                }
                        }
                        war->setmaster(nullptr);//set the warrior avilable for hire
                        totalstrength -= war->getstrength();
                        cout << "You don't work for me anymore " << war->getname() << "! -- " << name << "." << endl;
                }
                else 
                {
                        //send out the error message if the warrior does not work for the noble
                        cout<<"Error: You don't work for me at all! " << war->getname() << "! -- " << name << "." << endl;
                }
        }
        void setwarriors(float ratio) 
        {
                for (Warrior* war : warriors) 
                {
                        war->setstrength(int(ratio * war->getstrength()));
                }
        }
        //battle between two noble object
        void battle(Noble& nob) 
        {
                cout << name << " battles " << nob.name << endl;
                if (totalstrength == nob.totalstrength) 
                {
                        cout << "Oh, NO!  They're both dead!  Yuck!" << endl;
                        setwarriors(0);
                        nob.setwarriors(0);
                        totalstrength = 0;
                        nob.totalstrength = 0;
                }
                else if (totalstrength == 0) 
                {
                        cout << "He's dead, " << nob.name << endl;
                }
                else if (nob.totalstrength == 0) 
                {
                        cout << "He's dead, " << name << endl;
                }
                else if (totalstrength > nob.totalstrength) 
                {
                        cout << name << " defeats " << nob.name << endl;
                        nob.setwarriors(0);
                        setwarriors(1 - nob.totalstrength / totalstrength);
                        totalstrength -= nob.totalstrength;
                        nob.totalstrength = 0;
                }
                else 
                {
                        cout << nob.name << " defeats " << name << endl;
                        setwarriors(0);
                        nob.setwarriors(1 - totalstrength / nob.totalstrength);
                        nob.totalstrength -= totalstrength;
                        totalstrength = 0;
                }
        }
private:
        string name;
        vector<Warrior*> warriors;
        float totalstrength = 0;//total strength of the warriors
};
//return pointer to the warrior with the name; nullptr if none;
Warrior* getWarrior(const string& name, const vector<Warrior*>& warriors) 
{
        for (size_t index = 0; index < warriors.size(); ++index) 
        {
                if (warriors[index]->getname() == name) { return warriors[index]; }
        }
        return nullptr;
}
//return pointer to the noble with the name; nullptr if none;
Noble* getNoble(const string& name, const vector<Noble*>& nobles) 
{
        for (size_t index = 0; index < nobles.size(); ++index) 
        {
                if (nobles[index]->getname() == name) { return nobles[index]; }
        }
        return nullptr;
}
//display all the nobles in the vector;
void Nobledisplay(const vector<Noble*> nobles) 
{
        cout << "Nobles:" << endl;
        if (nobles.size() == 0) 
        {
                cout << "None" << endl;
        }
        else 
        {
                for (size_t index = 0; index < nobles.size(); ++index) 
                {
                        cout << *nobles[index] << endl;
                }
        }
}
//display all the warriors in the vector;
void Warriordisplay(const vector<Warrior*> warriors) 
{
        bool is_empty = true;
        cout << "Unemployed warriors:" << endl;
        for (size_t index = 0; index < warriors.size(); ++index) 
        {
                if (warriors[index]->getmaster() == nullptr) 
                {
                        is_empty = false;
                        cout << *warriors[index] << endl;
                }
        }
        if (is_empty) { cout << "None" << endl; }
}
//clear all the noble pointers
void Nobleclear(vector<Noble*> nobles) 
{
        for (size_t index = 0; index < nobles.size(); ++index) 
        {
                delete nobles[index];
        }
}
//clear all the warrior pointers
void Warriorclear(vector<Warrior*> warriors) 
{
        for (size_t index = 0; index < warriors.size(); ++index) 
        {
                delete warriors[index];
        }
}


int main() 
{
        ifstream ifs("nobleWarriors.txt");
        string type,noble_name,warrior_name,noble_name2;
        vector<Noble*> nobles;
        vector<Warrior*> warriors;
        int strength;
        Noble* noblep;
        Noble* noblep2;
        Warrior* warriorp;
        while (ifs >> type) 
        {
                if (type == "Noble") 
                {
                        ifs >> noble_name;
                        if (getNoble(noble_name, nobles)!=nullptr) 
                        {
                                cout << "Error: noble already exists: " << noble_name << endl;
                        }
                        else 
                        {
                                nobles.push_back(new Noble(noble_name));
                        }
                }
                else if (type == "Warrior") 
                {
                        ifs >> warrior_name >> strength;
                        if (getWarrior(warrior_name, warriors)!=nullptr) 
                        {
                                cout << "Error: warrior already exists: " << warrior_name << endl;
                        }
                        else 
                        {
                                warriors.push_back(new Warrior(warrior_name,strength));
                        }
                }
                else if (type == "Hire") 
                {
                        ifs >> noble_name >> warrior_name;
                        noblep = getNoble(noble_name, nobles);
                        if (noblep == nullptr) 
                        {
                                cout << "Error: noble does not exist " << noble_name << endl;
                        }
                        else 
                        {
                                warriorp = getWarrior(warrior_name,warriors);
                                if (warriorp == nullptr) 
                                {
                                        cout << "Error: warrior does not exist: " << warrior_name << endl;
                                }
                                else 
                                {
                                        noblep->hire(warriorp);
                                }
                        }
                }
                else if (type == "Fire") 
                {
                        ifs >> noble_name >> warrior_name;
                        noblep = getNoble(noble_name, nobles);
                        warriorp = getWarrior(warrior_name, warriors);
                        if (noblep == nullptr) 
                        {
                                cout << "Error: noble does not exist " << noble_name << endl;
                        }
                        else 
                        {
                                noblep->fire(warriorp);
                        }
                }
                else if (type == "Battle") 
                {
                        ifs >> noble_name >> noble_name2;
                        noblep = getNoble(noble_name, nobles);
                        noblep2 = getNoble(noble_name2, nobles);
                        if (noblep == nullptr || noblep2 == nullptr) 
                        {
                                if (noblep == nullptr) 
                                {
                                        cout << "Error: noble does not exist: " << noble_name << endl;
                                }
                                if (noblep2 == nullptr) 
                                {
                                        cout << "Error: noble does not exist: " << noble_name2 << endl;
                                }
                        }
                        else 
                        {
                                noblep->battle(*noblep2);
                        }
                }
                else if (type == "Status") 
                {
                        cout << "Status\n======" << endl;
                        Nobledisplay(nobles);
                        Warriordisplay(warriors);
                }
                else 
                {
                        Nobleclear(nobles);
                        Warriorclear(warriors);
                        nobles.clear();
                        warriors.clear();
                }
        }
}


==========================================================================

nobleWarriors.txt

Noble King_Arthur
Noble Lancelot_du_Lac
Noble Jim
Noble Linus_Torvalds
Noble Bill_Gates
Warrior Tarzan 10
Warrior Merlin 15
Warrior Conan 12
Warrior Spock 15
Warrior Xena 20
Warrior Hulk 8
Warrior Hercules 3
Hire Jim Spock
Hire Lancelot_du_Lac Conan
Hire King_Arthur Merlin
Hire Lancelot_du_Lac Hercules
Hire Linus_Torvalds Xena
Hire Bill_Gates Hulk
Hire King_Arthur Tarzan
Status
Fire King_Arthur Tarzan
Status
Battle King_Arthur Lancelot_du_Lac
Battle Jim Lancelot_du_Lac
Battle Linus_Torvalds Bill_Gates
Battle Bill_Gates Lancelot_du_Lac
Status
Clear
Status

sample output


Related Solutions

The C++ question: This part of the assignment will give you a chance to perform some...
The C++ question: This part of the assignment will give you a chance to perform some simple tasks with pointers. The instructions below are a sequence of tasks that are only loosely related to each other. Start the assignment by creating a file named pointerTasks.cpp with an empty main function, then add statements in main() to accomplish each of the tasks listed below. Some of the tasks will only require a single C++ statement, others will require more than one....
determine which part of the endocrine system could be experiencing problems. List some other info that...
determine which part of the endocrine system could be experiencing problems. List some other info that could confirm or rule out your initial diagnosis (test you might be able to run or questions to ask the patient or relatives). Explain your reasoning. A 27 year old female enters the clinic complaining of fatigue, fluid retention (especially in her face), and a cold that she just cannot kick. She is studying for her midterms (she is a first year physician's assistant...
Assignments : A. Film Analysis Related to Interpersonal Communication Background on the Assignment: In a written...
Assignments : A. Film Analysis Related to Interpersonal Communication Background on the Assignment: In a written assignment of approximately 1,000 words, examine how the insights you gained from course readings thus far relate to some of the characters, scenes or plot in a film that you have viewed. Students are encouraged to select from a wide array of films, from independent productions to Hollywood hits. This analysis should include three parts: Part One: Explain the interpersonal communication concepts/competencies that you...
Only Question 2 (a, b, c) , but Question 1 is more background information. An experiment...
Only Question 2 (a, b, c) , but Question 1 is more background information. An experiment focuses on the differences among apple species. Species A was randomly selected out of 4 species in the experiment 1. What if you want to choose Spcies A. ali or Species A. pub. What is the probability that you choose one or the other? a. P(A. ali or A. pub) = b. This can be done by adding probabilities. Write an equation if possible....
Background Info: What is the percentage of debt used to finance Gap? ___56%_____ What is the...
Background Info: What is the percentage of debt used to finance Gap? ___56%_____ What is the percentage of owner’s equity used to finance Gap? _44%_____ Question: What is the significance of these two percentages?
Give some examples of non-feeding larvae from several phyla or other tax Give some examples of...
Give some examples of non-feeding larvae from several phyla or other tax Give some examples of feeding larvae from several phyla or taxa. Use appropriate names for the phyla and the larval types. How does having a nonfeeding larva fundamentally alter the ecology and population biology of an organism?
required info: Question 1: Rebel without a cause Two drivers speed head-on toward each other and...
required info: Question 1: Rebel without a cause Two drivers speed head-on toward each other and a collision is bound to occur unless one of them deviates at the last minute. If both deviate, everything is okay (they both win 1). If one deviates and the other does not, then it is a great success for the driver with iron nerves (he wins 2) and a great disgrace for the deviating driver (he loses 1). If both drivers have iron...
in the background of Covid 19 epidemic please give some legal suggestions to companies when doing...
in the background of Covid 19 epidemic please give some legal suggestions to companies when doing international business
Background Hands-On Assignments are designed to foster independent thinking and problem solving programming skills. This activity...
Background Hands-On Assignments are designed to foster independent thinking and problem solving programming skills. This activity is closely guided by the course instructor. Students are encourages to ask instructor any questions related to this challenge. Similar to the course Exercises, this activity also has a Base Code. The initially given Base Code to Start with this assignment: This assignment is based on the project 6.9 of the course book. --------------Start---------------- buttondemo.py      breezypythongui.py --------------End ---------------- --------------------------------------- Prompt Task to Accomplish...
Brief Case Assignment #2 Requirement: Read the background info below. Assume the role of a CPA...
Brief Case Assignment #2 Requirement: Read the background info below. Assume the role of a CPA who has been asked by your client (the controller of Clarkson Outdoors, Inc.) to provide some accounting guidance for shipping and “handling” charges for internet sales. Use your available research resources (GAAP codification, textbook) to research the accounting questions asked by the controller. Prepare a brief (no more than one - page) memo to the controller that addresses, in your own words, the alternatives...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT