Tic Tac Toe


General

  • All submissions must include a work history to be worth credit.
  • Submit all files to elearn. Make sure to name file(s) EXACTLY as specified - including capitalization.
  • Make sure your program accepts input in EXACTLY the order and format given. Do not ask for extra input or change the order of inputs.
    If you want to make an expanded version of a program that and get feedback on it, email it to me or show me in class.
  • Slight variations in output wording/formatting are usually fine (as long as formatting isn't part of the assignment).
    If you do not get the right final output, print out some evidence of the work your program did to demonstrate your progress.
  • Readability and maintainability of your code counts. Poor formatting, confusing variable names, unnecessarily complex code, etc… will all result in deductions to your score.

Objective

Upon completion of this assignment the student will be able to create classes to represent complex data types.

Requirements

Submit file: assign1.zip

For each assignment, you will submit a .zip archive of your project folder including all its contents.

If needed you can review instructions on making a .zip archive. Make sure to compress your assign1 folder, not just your code file.

I should be able to build your code with:

g++ -g -std=c++17 TicTacToe.cpp tests.cpp -o tests.exe

Your code MUST compile with an unmodifed version of the provided tests (see below).

Setup

Make a Unit Test project and replace the contents of tests.cpp with the contents of this file tests.cpp.

Since I will use my own version of tests.cpp, do not modify it to match your code! You can modify the tests if you want to test out something not already checked in them, but make sure that your code builds against the provided file.

Then add a new file and name it TicTacToe.h and a second new file named TicTacToe.cpp. Add the two files to the HEADERS and TEST_FILES sections of the Makefile.

# list .h files here
HEADERS = TicTacToe.h

# list .cpp files here
TEST_FILES = tests.cpp TicTacToe.cpp

Overview

Implement the class TicTacToe shown below. It is an object that represents the state of a game of TicTacToe and has methods to make moves and check if someone has won. Note that it does not have to play the game, just keep track of a game.

TicTacToe Class

The TicTacToe class should not have any input or output code (no cin/cout).

Start by stubbing out all the functions (see list below below). A stub version of a function is one that just returns some default value without even trying to do its job correctly.

  • A stub constructor or void function does nothing in its body
  • A stub function that returns a value should just returns some default value like 0 or false or ""

Once you can compile against all the tests, you can start worrying about trying to actually pass them. If your program does not compile because you are missing functions, I will not be able to verify the rest of your code works!

Implementation Details

Variables

board should be a 3x3 array of chars. It stores the current state of the board.

The currentPlayer keeps track of whose turn is next. This should always either be 'X' or 'O'.

You should not need other class level variables. If you add any, make sure they do not duplicate existing information or anything that can be determined from existing information.

Functions

Below are descriptions of what the functions should do. You can add extra functions if you like, but must implement the ones listed in the UML and they must behave as described below.

Avoid duplicating code from functions. Instead, call other functions when appropriate.

Your .h file should have Doxygen comments for each function.

TicTacToe()

Not listed in UML by convention as the default constructor is the only option

Sets all board squares to empty value. Sets currentPlayer to 'X' (X always goes first).

There is no magic way to initialize all elements of an array with one statement inside the constructor. You need to initialize the array where it is declared or use a loop to initialize the elements in the constructor.

char getCurrentPlayer()

Returns the player who goes next ('X' or 'O')

bool isValidMove(int row, int col)

row and col will both be specified as 0-2.

Checks to see if the given row and column are valid values (0-2) and if the given location on the board is empty. If so, return true. Otherwise, return false.

void makeMove(int row, int col)

row and col will be specified in human numbers: 0-2.

Check to see if the location specified is valid (as defined above).

If not, do nothing. If so, sets that location to hold the mark of the current player. Then changes the current player to be the other player (switches from 'X' to 'O' or vice verse).

char getWinner()

Checks to see if a player has won (they have three in a row, three in a column, or three on one of the two diagonals). If so, return the winner ('X' or 'O'). If no one has won, returns '-'.

The behavior if there are multiple winners is undefined. (Don't worry about how to handle if the game goes too long and X and O both have a way to claim a win.)

bool isDone()

Returns true if someone has won or there are no more moves to make.

string toString()

Return a string representation of the board. Use '-' chars for empty squares, place a space between each column (but not after the last column) and a newline (\n char) after each row but the last.

X - -
- O -
- - X

Advice

If your code does not build, or never finishes running, I can't effectively grade it. Make sure one part of your code doesn't completely break the program and prevent later parts from ever running. If you have an attempt at a function that causes the tests to crash, comment out that code and provide a stub version of the function (return 0/false/etc...).

You can still get some points for commented out code. If you leave broken code in however, and it prevents me from testing the rest of your code, you will end up not getting full credit for anything!

Play TicTacToe - Optional

Once your class is done, if you want to use it to play TicTacToe, you can make a Basic Project, add your .h and .cpp files to it, update the Makefile to include the two files, and then add this code to the main.cpp file.

Challenge - Optional

This is ungraded - it is simply a fun extension if you get done early and want to extend your program

Add a function to have the computer make a move for the current player:

void makeAutoMove();

You can make it pick random (available) squares or actually work at making it smart. Just like makeMove, it should both make the move and then switch the current player.

You can either write your own tests for it, or you can use the main.cpp provided above to test it by playing the computer.