The objectives of this project are 1) to practice designing C++ derived classes, and 2) to practice using polymorphism in C++.
The program for this project is a game/simulation that involves a bunch of "characters" in a dungeon/maze. The dungeon consists of rooms. Each room is connected to some of the other rooms, as specified by a map. Characters that are in the same room interact with each other. Characters also wander from room to room.
During each turn of the simulation, the following will happen, in this order:
1. Dead characters are removed.
2. Each character interacts with one randomly selected character who is in the same room. A character will not be asked to interact with himself/herself. If there is only 1 character in a room, then no interaction take place.
3. Each character migrates to a neighboring room one that is connected to its current room, as specified by the map. Some characters do not migrate and stay in the same room.
4. Each character might transform into another character at the end of a turn. For example, a human who has been bitten by a zombie, might transform into a zombie.
These simulations are handled by the member functions in a Game class that is provided for you. This Game class only works with a base class called Character. To make the simulation interesting, you will derive classes from Character that must conform to some behaviors specified below. The character types that you will derive are: Zombie, Human, Doctor, Buffy, Vampire and RedShirt..
Here is the declaration for Character (comments removed):
class Character {
public:
Character() ;
virtual ~Character() ;
virtual void encounter(Character *ptr) = 0 ;
virtual void biteMe(Character *ptr) = 0 ;
virtual void hitMe() = 0 ;
virtual void cureMe() = 0 ;
virtual Character *morph() = 0 ;
virtual bool migrates() ;
virtual string identify() = 0 ;
unsigned int getId() ;
bool isDead() ;
protected:
bool m_isDead ;
private:
unsigned int m_id ;
static unsigned int m_counter ;
} ;
The Character class has many pure virtual functions. This allows code in the Game class to call member functions defined by the derived classes that you will write.
Here's the intended use for each function:
Your assignment is to write/design classes derived from the Character class. Your derived objects must conform to the behavior described below.
These are the classes you have to implement:
1. The files provided to you have been placed here:
/afs/umbc.edu/users/c/h/chang/pub/cs202stuff/proj4/
Except for main.cpp, you should not change the content of these files.
character.cpp
character.h
game.cpp
game.h
ghost.cpp
ghost.h
linked.cpp
linked.h
main.cpp
node.cpp
node.h
2. Here is an example of the output from the program: proj4-output.txt. You do not have to make your output look exactly like this.
3. Note that the Character class is an abstract class because it has pure virtual member functions. (That what those =0's at the end of the member function declarations mean.) So, you cannot create a Character object. You can only create objects of derived classes that have every pure virtual member function defined.
4. Your implementation should not rely on runtime type checking. In particular, your implementation should allow for future class derivations. For example, we should be able to introduce a new Werewolf class that bites. Then, without changing your code, your Humans should turn into Werewolves after 3 turns if they are bitten by a Werewolf.
5. How does a Human know to morph into a Zombie or a Vampire? When a Zombie invokes the biteMe() function, it has to pass a new Zombie object to biteMe(). The biteMe() function must store a pointer to this Zombie object. After 3 turns, when the Human morphs, this pointer must be returned to the Game class which will replace the Human with a Zombie. Similarly, when a Vampire bites a Human, it should pass in a new Vampire object. Thus, a Human bitten by a Vampire becomes a Vampire and a Human bitten by a Zombie becomes a Zombie.
6. Watch out when a Human who was bitten gets cured. You have to delete the pointer to the Vampire or Zombie that you stored somewhere. If you do not, then you will have a memory leak. Use valgrind on GL to check your program for memory leaks. The syntax for invoking valgrind is:
valgrind ./a.out
assuming that your executable file was named a.out.
7. You should not use any global variables.
8. Note that the phases of each turn take place in lock step. For example, all the characters interact before any of them morph. This means it is possible for a Human who was just cured by a Doctor to be bitten again in the same turn. Also, a Zombie who was just cured by a Doctor, might suffer some hits from Buffy (and die) during the same turn because the transformation to human takes place in the last phase.
9. The Ghost class implementation in ghost.h and ghost.cpp should help you get started with the C++ syntax for class derivations.
10. If you copy ghost.h to make a header file for another class, make sure you change the guards at the top of the file.