Problem:

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.

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.

Input:

Our sample input file might now look like:

Warrior Jim Glamdring 42
Warrior Lancelot Naegling 15
Warrior Arthur Excalibur 15
Warrior Torvalds Narsil 20
Warrior Gates Orcrist 8
Status
Battle Arthur Lancelot
Battle Jim Lancelot
Battle Torvalds Gates
Battle Gates Lancelot
Status

The corresponding output would be:

There are: 5 warriors
Warrior: Jim, weapon: Glamdring, 42
Warrior: Lancelot, weapon: Naegling, 15
Warrior: Arthur, weapon: Excalibur, 15
Warrior: Torvalds, weapon: Narsil, 20
Warrior: Gates, weapon: Orcrist, 8
Arthur battles Lancelot
Mutual Annihilation: Arthur and Lancelot die at each other's hands
Jim battles Lancelot
He's dead, Jim
Torvalds battles Gates
Torvalds defeats Gates
Gates battles Lancelot
Oh, NO! They're both dead! Yuck!
There are: 5 warriors
Warrior: Jim, weapon: Glamdring, 42
Warrior: Lancelot, weapon: Naegling, 0
Warrior: Arthur, weapon: Excalibur, 0
Warrior: Torvalds, weapon: Narsil, 12
Warrior: Gates, weapon: Orcrist, 0

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.

Programming Constraints

What would a homework assignment be without unnecessary and unreasonable constraints?

Your classes must satisfy the following:

  • The battle method will announce who is battling whom, and the result (as shown in the example output).
  • If one or both of the nobles is already dead, just report that.
  • The "winner" doesn't win anything for kicking around a dead guy. And his warriors don't use up any strength.
  • Look at the output for the sample test program to see what you should be displaying.
  • A noble's army is a vector of pointers to warriors. Warriors will be ordered in the army by the order in which they were hired. That affects how you remove a Warrior that gets fired.

And some things to make life easier, Just in case you are confused, let me point out that this problem does not involve the use of the heap. That means your program will not make use of the operator new or the operator delete.

==========
Status before all battles, etc.
Jim has an army of 1
Spock: 15

Lancelot du Lac has an army of 2
Conan: 12
Hercules: 3

King Arthur has an army of 2
Merlin: 15
Tarzan: 10

Linus Torvalds has an army of 1
Xena: 20

Bill Gates has an army of 1
Hulk: 8

==========
You don't work for me anymore Tarzan! -- King Arthur.
King Arthur has an army of 1
Merlin: 15

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 after all battles, etc.
Jim has an army of 1
Spock: 15

Lancelot du Lac has an army of 2
Conan: 0
Hercules: 0

King Arthur has an army of 1
Merlin: 0

Linus Torvalds has an army of 1
Xena: 12

Bill Gates has an army of 1
Hulk: 0

==========

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

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.
  • The input file will be named "nobleWarriors.txt".

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!)

Example input file (no errors):

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

Example 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
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.