CSCI 261 Programming Concepts (C++)

Winter/Spring 2012

Homework 29: Troll Battle

Right-click me and select "Save target as..." to save.

Concepts

Focus on one two central concepts for this assignment: declaring functions in external files, and passing objects by reference to functions.

Passing by Value

To this point, we've been adhering to the idea that usually, when a function receives an argument, it receives it as a "copy" of the variable's value. For example:

void someFunc(int x) {
    x += 5;
    cout << "The value I received is now " << x << endl;
}

int candy = 20;
someFunc(candy);

cout << "candy is still " << candy << endl;

What is printed to the screen above? "The value I received is now 25" followed by "Candy is still 20." Remember, when we call a function and pass it an argument, we pass a copy of that argument's value. Anything the function does to those values (via the parameter names, in this case x) is completely independent of the world outside the function.

Passing by Reference

There are cases where we do want the function to be able to manipulate values outside of its scope -- specifically, when we define functions that expect to receive objects. You witnessed some examples in class, so we'll merely demonstrate the syntax here.

void someFunc(int &x) {
    x += 5;
    cout << "The value that is referenced is now " << x << endl;
}

int candy = 20;
someFunc(candy);

cout << "candy is now " << candy << endl;

What is printed to the screen above? "The value that is referenced is now now 25" followed by "Candy is now 25."

If this seems strange, imagine that when you prefix a parameter with &, there is a thread attached to the parameter that is tied to the original variable passed to the function. In this case there's a "connection" between candy and x, in that they are names of the same value in memory.

Declaring Functions in External Files

When we introduced functions, we first wrote the entire function implementation above main. Then, as the number of functions we use increased in number, we chose to declare function prototypes above main and the implementations below main.

Did you notice how the past few assignments had a file called test.h that contained function prototypes, and a test.cpp that included the implementations of those functions? From now on, we'd like you to do the same: defining global functions in external files. Specifically: write your function prototypes in the header (.h) file, and the implementation in the implementation (.cpp) file.

For this project, we've provided battle.h and battle.cpp which should contain your global functions.

Instructions


Ghandi, with old laptop.
Attribution: freedomarchives.org

While we certainly feel that non-violence is best, most trolls apparently do not agree with this philosophy. In fact, according to legend, most trolls love a skirmish now and then. To them, it's a form of camaraderie and a means to eat (especially eating Mines students, so we hear). In this assignment, you will write a program that simulates a battle between two trolls.

In the past few assignments, we have been specific about the API that your classes must support. In this assignment, we will be describing the problem and algorithms in English, and your goal is to translate those requirements into proper C++ code.

When complete, your program should generate the following console output:



John (health: 74, strength:9)
Jane (health: 65, strength:7)
John is fighting Jane!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
Jane attacks John doing 7 damage!
John attacks Jane doing 9 damage!
John (health: 25, strength:9)
Jane (health: -7, strength:7)
John is the victor!

The output you see above is the result of two Trolls that engage in a fight, a description of each "round" of the fight, and a declaration of the winner of the fight.

Our model of Trolls is simple: they have three attributes, a name, a numeric health and a numeric strength; and just one behavior, the ability to attack another Troll. Yes, our Troll has a very one-dimensional behavior.

A Troll's health is some number between 0 and 100, determined at random upon instantiation. A Troll's strength is some number between 0 and 10, also determined at random upon instantiation. When Troll A attacks Troll B, then Troll B's health should be decremented by an amount equal to Troll A's strength.

For example, consider Troll A with a health of 50 and a strength of 5, and Troll B with a health of 30 and a strength of 10. When Troll A attacks Troll B once, then Troll B's health becomes 25. When Troll B attacks Troll A once, then Troll A's health becomes 40.

This attack behavior should be represented by a member function called attack that accepts a Troll parameter, the target of the attack. It should also print "M attacks N doing X damage!" where M and N are the names of the attacking Troll and the attacked Troll, respectively, and X is the attacking troll's strength.

The fight algorithm should implement a fight to the death: given two Trolls, they should attack each other until one Troll's health reaches 0. This algorithm should be implemented as a global function called fight that accepts two Troll parameters. It should print "M is fighting N!" where M and N are the names of the two fighting Trolls.

After the battle, a function called declareWinner should be called, which also accepts two Troll parameters. This function should check to see which Troll is left standing (has a health greater than 0) and prints a message declaring the winner to the console, such as "John is the victor!"

In a nutshell, your main implementation should:

  1. Instantiate two trolls, A and B.
  2. Print the name, health and strength of each Troll.
  3. Call your fight function, passing it both Trolls.
  4. Print the name, health and strength of each Troll, after the fight.
  5. Call your declareWinner function, passing it both Trolls.

For this assignment, a basic test suite is provided to help guide your implementation of the Troll class and the two global functions fight and declareWinner. Once you pass the test suite, you may comment out runAllTests() in main.

Note that for this assignment, you do not need to implement accessor methods ( eg getHealth() ) and can simply make member variables public.

Hints

Start by trying to pass the test suite. You'll need to define a Troll, and to define two global functions fight and declareWinner.

When passing the test suite, don't worry so much about the implementations of attack, fight and declareWinner. We recommend leaving the bodies of those functions empty until you pass the test suite.

The return types of attack, fight and declareWinner should be void.

Once you pass the test suite, comment out the runAllTests() line in main and then complete your function implementations.

main should print each Troll's attributes to the console before and after the battle.

fight should print "Troll A is fighting Troll B" with appropriate Troll names, of course. It should then cause Troll A to attack Troll B, and Troll B to attack Troll A, over and over again, until one of your Troll's health reaches 0.

The Troll's attack method should print "A attacks B doing N damage!" where A and B are the names of the Trolls and N is the strength of Troll A.

declareWinner should receive two Troll parameters and print the name of the victor. The victor is obviously the Troll that has more than 0 health remaining.

Requirements and Rubric

This work is worth 220 points.

Requirement Points Notes
Place your name in the comment header in main.cpp 5
Correct submission of src directory as a .zip file. 5
Exhibits good programming style. 20
Does not print test results to the screen 10 Comment out the test executor when done!
main instantiates two Troll objects passing a name to the constructor 20
main prints the attributes of two Trolls before the fight 20
main calls fight function, passing two troll objects 20
"A is fighting B" is printed to the screen 20 A and B are Troll names
"A attacks B doing N damage!" is printed to the screen 10 A and B are Troll names, N is A's strength
"B attacks A doing M damage!" is printed to the screen 10 A and B are Troll names, M is B's strength
main prints the attributes of two Trolls after the fight 20
The after-fight attributes printed shows one troll with health <= 0 20
main calls declareWinner function, passing two troll objects 20
"X is the victor!" is printed to the screen 20 where X is the Troll with > 0 health remaining

Concepts Exercised: OOP, classes, functions, pass-by-reference, simulation, fun, repetetive tasks, making decisions, modeling