MCS273 Introduction to C++ Programming (January 2013)

Robots and polymorphism


Overview

In this lab you will change a completed Robots game to include polymorphism. To get started, you should first download the file Robots.zip to convenient location and import it into Eclipse. This is an implementation of the Robots program written by David Wolfe and will be the starting point of your programming. Compile and play the game once to observe its behavior. (I am providing a functioning Makefile which will make this easy.) Next, familiarize yourself with the code. First, skim the README file. I recommend you look at the Unit class, the GameState class and the Game class.

As I said above, your goal is to incorporate polymorphism into the Robots program. There are several places where polymorphism is appropriate in this program.

  • All units on the board need to be able to draw themselves, yet they draw themselves differently.
  • The vector of robots and the vector of junk can really be stored as a single vector of stuff on the board. We'll say that junk "is a" robot which just happens to not move. To keep things simple, when two robots collide, there will be two junk heaps at the location.

Required tasks for adding polymorphism

In order to help you incorporate polymorphism into the Robots program, we give you the following step-by-step approach:

  1. Make draw() virtual in the Unit class and update subclasses appropriately. For this part of the lab, the Unit class need not be pure-virtual; just leave the most common case for the virtual procedures in Unit.cc. Subclasses will only need to override those definitions if they need to. You'll need to add a procedure draw() to Unit.cc which does nothing (or, if you prefer, flags an error). Recompile and run.

  2. Make Junk a subclass of Robot. (You'll need to add a constructor to the Robot class which is called by Junk's constructor.) Recompile and run.

  3. Add a virtual function isJunk() to the Robot class, updating the subclass Junk appropriately. This method should return bool depending on whether the Robot is Junk Recompile and run.

  4. Make moveTowards() and attacks() virtual in the Unit class. You should not override the Unit implementations for moveTowards() and attacks() in Robot, but you should override them appropriately in Junk. Recompile and run.

  5. Quite a few changes are required to the GameState class so that only one vector of vector<Robot *> is maintained. (There won't be a vector of Junk.) Make the appropriate changes. Most changes are simple. More significant changes to the logic are required in the constructor and in countCollisions(). The latter procedure can be vastly simplified to make no reference to junkAt(). In fact, you should be able to remove the procedure junkAt() from the GameState class.

  6. Review GameState procedure by procedure once more to be sure all required changes were made. Then, try compiling and debugging, checking that the program runs correctly.

  7. Unfortunately, your robots program probably now has a memory leak. There are lots of robots that get created, but never get destroyed. If a player would do really really well in the game, and play for hours, eventually the program would run out of space, bringing it to a grinding halt.

    Add a static variable unit_count to Unit.cc by placing the following line at the top of Unit.cc:

        static int unit_count = 0;
    
    This variable will have file scope.

    Edit Unit.cc so that every call to any of the three Unit::Unit(...) constructors increments unit_count. Make a virtual destructor Unit::~Unit() whose only purpose is to decrement unit_count. (The destructor needs to be virtual since the class is virtual.)

    Recompile and run your program in the debugger. After playing two levels, set a breakpoint in one of the Unit classes, continue, and (lastly) inspect the variable. Is the value reasonable? If it keeps growing as you go from level to level, you still have a memory leak.

  8. Check-off (4 points) Be sure to get checked off for this lab.