Question: Part A: Convert the Tile Module to a Class [35% = 24% test program + 11% code] In Part A, you will convert the Tile
Part A: Convert the Tile Module to a Class [35% = 24% test program + 11% code]
In Part A, you will convert the Tile type to an encapsulated class. You will also add a class invariant that requires the tile genus to be strictly less than GENUS_COUNT.
By the end of Part A, your Tile class will have the following public member functions:
Tile ();
Tile (unsigned int genus1, unsigned int species1);
bool isOwner () const;
unsigned int getAffectedPlayer ( unsigned int whose_turn) const;
unsigned int getGenus () const;
unsigned int getSpecies () const;
void setOwner (unsigned int owner1);
void activate (unsigned int whose_turn) const;
void print () const;
You will also have the following private member functions:
void printOwnerChar () const;
void printGenusChar () const;
void printSpeciesChar () const;
bool isInvariantTrue () const;
Perform the following steps:
- Convert the Tile record to a class. The fields should become private member variables.
- Convert the Tile-associated functions to member functions in the interface (i.e., .h) and implementation (i.e., .cpp) files. The tilePrint*Char functions should be private and the others should be pubic. The tileCreate function should become the non-default constructor. Remove the word tile from the function names and change the new first letter to lowercase. In the implementation file, add Tile:: before every function name.
- Reminder: A * in a name means "anything". So tilePrint*Char refers to three functions.
- Reminder: If a member function calls another member function, you will have to update the name in the call as well.
- Remove the Tile parameter from all the functions. Inside the functions, update the member variables to not use dot notation. For example, tile.genus should become plain genus.
- Add a default constructor that sets the owner to NO_OWNER, the genus to GENUS_MONEY, and the species to 1. Remember to add the function prototype.
- Note: If we don't declare a default constructor, the compiler will not allow us to declare an array of Tiles. (Because it has to call the default constructor for each element when an array is created.) So we need the default constructor or the board won't work.
- Add a precondition to the non-default constructor that requires the genus1 parameter to be strictly less than GENUS_COUNT. Use an assert to enforce the precondition.
- Reminder: Every constructor must initialize every member variable. In this case, your constructor must initialize the genus, the species, and the owner.
- Add a private const member function named isInvariantTrue to check the class invariant. It should return true if the tile genus is strictly less than GENUS_COUNT and false if it is the same or greater.
- Check the class invariant at the end of every non-const public member function. For the Tile class, this is both constructors and setOwner. At the end of each of these functions, use an assert to make sure that isInvariantTrue returns true: assert(isInvariantTrue()); The purpose of this is to ensure that these functions do not leave the Tile in an invalid state. The const functions cannot change the tile state, so we don't need to check the invariant there.
- Note: Don't check the invariant in private functions. It will be checked in the functions that call them.
- Check the class invariant at the start of every public member function except the constructors. Use an assert to make sure that isInvariantTrue returns true. The purpose of this is to ensure that the Tile in a valid state when the function is called.
- Reminder: Don't check the invariant in private functions.
- Test your Tile module using the TestTile3.cpp program provided. As always, you will need TestHelper.h and TestHelper.cpp.
Part B: The Board Class [25% = 15% test program + 10% documentation]
In Part B, you will convert your board module to an encapsulated class. The Board class will not have a class invariant.
By the end of Part B, your Board class will have the following public member functions:
Board ();
void print () const;
const Tile& getAt (const CellId& cell_id) const;
void setAt (const CellId& cell_id, const Tile& value, unsigned int owner);
You will also have the following private member functions:
void printColumnNameRow () const;
void printBorderRow () const;
void printEmptyRow () const;
void printDataRow (int row) const;
Perform the following steps:
- Declare a Board class in Board.h. It should have a 2D array of Tiles as a private member variable. Remove the Board typedef.
- Convert the existing function prototypes to member functions or copy in the ones shown above. Update the functions in the Board.cpp implementation file to match the new prototypes.
- Convert the boardInit function into a default constructor. When assigning values to the board array, use the non-default Tile constructor. The syntax is: array_name[i][j] = Tile(put values for parameters here);
- Change the getAt and setAt functions to take a const reference to a CellId as a parameter instead of a row and a column. Use the row and column fields in the CellId parameter as the board position.
- Add a precondition to the getAt and setAt functions, enforced by an assert. It should require that the cell is on the board.
- Hint: You have a function to check that a cell is on the board.
- Add a parameter to the setAt function for the new tile's owner. The function should set the new tile on the board to have that owner. Add a precondition that the tile parameter does not already have an owner.
- Hint: Use a function from the Tile class to change the owner.
- Hint: Use the isOwner function from the Tile class to check whether a tile has an owner.
- Test your Board class using the TestBoard3.cpp program provided.
- Update your main function to use the new Tile and Board classes. It should run as before.
Hint: You will begin by declaring a variable of the Board type. Suppose it is named var (but you should use a better name!). When you declare a variable such as var and you do not put parentheses after the name of the variable, C++ will automatically call the default constructor. You do not need to explicitly call the default constructor. You should delete the call to the boardInit function.
Board var;
Hint: Suppose you used to call a function named boardFunc with a parameter of type Board as the first parameter. Now instead you want to call a function named func for an instance of the Board class, such as var. In this case, you first give the name of the variable, then a dot, then the name of the function, and then any parameters in parentheses. Suppose the old code was:
boardFunc(var, values for other parameters);
then the new code should be:
var.func(values for other parameters);
- Write interface specifications for the four public functions in the Board class. Use the format described in class and in Section 4a of the online notes. You do not have to write interface specifications for the private functions.
- Reminder: Interface specifications are written for other programmers who want to use your module.
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
