Programming In C++
Spring 2000


Homework #3 - Polymorphic Tic-Tac-Toe
Due: Feb 29th


This assignment involves extending your tic-tac-toe playing program to be even more object-oriented. You will need to develop more classes, including an abstract base class and 2 derived classes.

Player Base Class

In HW2 you had to write a player class that encapsulated your tic-tac-toe playing code. The idea was to provide a simple interface to your code through a small number of methods.

The problem with the player class from HW2 is that if we wanted to pit your player against my player we would need to rename the classes, since it would not be possible to have 2 player class definitions in the same file. This would mean that any tournament code that played one player against another would need to include code that knows about the names of player classes.

In this assignment you will create a base class named player that will be used by code that runs a tic-tac-toe match. There won't be any objects (variables) of type player directly created, instead there will be some derived classes. You will need to create at least 3 derived classes that can be played against each other:

Only 2 of these classes can participate in one game, but we will run matches against each pair of players (so you need to provide all three). The interface for your base class is identical to the interface used in HW2, it's listed below, including some comments that indicate whether the methods should be virtual or not.

The player will contain methods that can be used to make a move in a game of tic-tac-toe. Within your class definition you can do anything you want (as far as defining data members and methods), but you must support the following methods:

Method prototype Description
player(int playernum); constructor that takes a single argument that specifies whether the object is player 1 or player 2 (playernum will be a 1 or a 2).
bool makemove(board &b); In the base class this should be a virtual method! This is different for different kinds of player classes! The makemove method in derived classes should change the board object so that one of the zeros in the board is changed to the player's number (the player makes a move). If a move is not possible the method returns false, otherwise the board should be updated and the method returns true.
bool has_won( board b); A boolean function that returns true if the player has won, otherwise returns false. Note that this method can be the same for each type of player, so it should be implemented in the base class and not in the derived classes.
bool has_lost( board b); A boolean function that returns true if the player has lost the game, otherwise returns false. Note that this method can be the same for each type of player, so it should be implemented in the base class and not in the derived classes.
For player objects you should make sure you have the following 4 class definitions:

// the base class
class player {
 . . .
};


// derived class - this one is the smart one

class smart : player {
 . . .
};

// derived class - this one is the dumb one

class dumb : player {
 . . .
};

// derived class - this one is the human player
class human : player {
 . . .
};

Class game

Once you have defined these classes, you can write a tic-tac-toe game class that can play 2 player (the base class) objects against each other. Most of this code is available as the test code for HW2 - you should put this code inside a new class called game with the interface shown below:

Method prototype Description
game(player &p1, player &p2); constructor. This constructor has 2 arguments, each is a reference to a player object ( we give it 2 objects of type player even though we know each of these is really an object of a derived class). If you need to do any initialization it should take place here.
int play(void); plays an entire game between the 2 player objects specified in the constructor. The player object p1 goes first. The return value should be 1 if player 1 was the winnner, 2 if player 2 was the winner or 0 if the game was a draw (a tie).

play should play an entire game, so it should start out by clearing the board (it may be called multiple times!).

play should print out each move of the game (the resulting game board) as was done with the first 2 projects.


HW2 board object

The board class from HW2 will need to be used by your game class (and is necessary to include since that is part of the definition of the player objects).

Test Code

A sample main program that uses these classes to play a match between 2 players is included below (notice how small this has now become!):
#include 
#include "board.h"
#include "player.h"
#include "smart.h"
#include "dumb.h"
#include "human.h"
#include "game.h"

int main(void) {

human h(1);
smart s(2);
game tttgame(h,s);    // create a game object

int result = tttgame.play();

if (result==1) 
   cout << "The Human won" << endl;
else if (result==2)
   cout << "smart player was the winner" << endl;
else
   cout << "Tie Game" << endl;
}

Submission

For this assignment you should create a header file (a ".h") file for each class you define. You can put the entire class definition in the header file, or if you like, put part of it in a corresponding ".cpp" file. Your code should work with the above main program, and it should work with any combination of the 3 types of players.

To submit your homework you should attach all your files to an email message sent to cpp-submit@cs.rpi.edu with the subject line set to Subject: HW3. You must also include a brief description of your code in a file named README (attach this file as well), including the names of all the files you are submitting and how you built a test program (if you use Visual C++ just say so, if you use a Unix C++ compiler you should tell us how you compiled the program).

You may submit up to 10 times, we will grade the last submission received.

Send email to cpp@cs.rpi.edu if you have questions or trouble emailing your submission.