Tic Tac Toe (also known as "Naughts and Crosses" and "Three-In-A-Row") is a simple game played on a 3 x 3 grid (i.e. 9 squares), where 2 players take turns at adding their pieces (a naught or a cross) until either :
? One of the players gets three of their pieces in a straight line (in any row, column, or diagonal). The player who does this first is the winner.
? Or, there are no more free squares to move into, in which case the game is a draw.
Your task for this assignment is to write a program in C++ that enables you (or another user of your program) to play Tic Tac Toe against a computer opponent.
The rules for the game are as follows :
1. The human player will always be Naughts (0?s).
2. The computer player will always be Crosses (X?s).
3. The human player (i.e. the program?s user) will initially go first.
4. In all subsequent games, the player who won the last game will go first. If the game was a draw, then the last player who won a game will go first.
An example of the game in action is as follows :
For your next move: Enter the Row (1-3) : 1
Enter the Column (1-3) : 2
Computer Grabs the Next Empty Square !
(Row = 1, Col = 3)
| X | O | X |
| O | X | |
| O | X | O |
Computer = X Human = O
Your Tic Tac Toe program should contain the following functions :
1. Initialise_Game : a function to initialise / start the game, so that the game 3 x 3 grid is empty (i.e. contains no player or computer pieces), and a new game is ready to start.
2. Draw_Game_Board : a function to draw the game 3 x 3 grid, with the human and computer players? pieces in the grid.
3. Get_Humans_Move : a function to prompt for, validate, and process a turn or move for the human player. You can do this a number of ways. For example, one way is to prompt the user for a row and column for their move. This function should then check that the selected square is valid and free, and if it isn?t then it should display appropriate error messages and re-prompt for the move. When a valid move has been made, then this function should insert the human player?s piece where required in the grid.
4. Get_Computers_Move : a function to determine a reasonable move for the computer player, as follows :
a. See if middle square is empty / free - the best thing to do is grab the center square, if it is available.
b. Otherwise, use next available empty square. If the computer player still hasn't moved (i.e. it hasn't taken the center square) then all it can do is grab the next available empty square.
5. Check_Game_Status : a function to determine if we have a winner yet (either the human or computer player has 3 in a line), or whether the game is a draw (no more empty squares, and no player has 3 in a line).
In addition, you should develop a main program to call each of the above functions (and any other functions you develop) as required. To given you an idea of some of the basic processing your main program will need to perform, the following pseudo-code has been provided, but please note that this does not take into account all of the processing that is required :
while (game != over)
At the end of any game, your program should increment and display the number of wins, losses, and draws for the human player, depending on who won, or whether the game was a draw.
All of this code should be brought together within a DOS standard or EasyWin EXEcutable Project.
Development Hints and Tips : The Smoothest Path to Success !!
1. Check your notes and text for code and examples that may be useful to you in doing this assignment.
2. Writing dozens or hundreds of lines of code, without careful and thorough testing at each step of the way, will likely leave you with a mess of code that will take a great deal of effort to get working or with code that you cannot get to work at all. Developing code in this way is a very bad practice. Expecting a lecturer or tutor or somebody else to fix such carelessly and recklessly written code is not fair on them or you. Do not do this !!
3. The smoothest path to success is to start of very simply, build functionality into your program piece by piece, and then test it thoroughly before attempting to add further functionality.
4. Before you start, stop and think about things :
a. How you are going to store the game board ? A 1 D array is OK, or you can use a 2 D array.
b. How are you going to determine whether a square is free, or human player occupied, or computer player occupied ? i.e. what will you store in your array to indicate this ?
5. The two functions you should start off with are also the most simple : Initialise_Game and Draw_Game_Board. When you have written these, you can call these functions and run your program and you can ensure that the very basics are working before you proceed further. Don?t worry too much about making your output attractive at this stage ? this is something you should do right at the end (if you have time).
6. The next easiest function to develop is : Get_Humans_Move. When you have written this function, you can run your program and have a simple one-sided game to check that your Draw_Game_Board is working properly and showing pieces where the player has moved them, and that the Get_Humans_Move function is working properly and doesn?t allow you to move into invalid squares or squares that are already occupied.
7. The next easiest function to develop is : Check_Game_Status. In this function, you need to determine if there is a winner or if the game is a draw :
a. To determine if there is a winner, you need to check all rows, columns, and diagonals, to see if any player (human or computer) has 3 pieces in a line. This isn?t particularly difficult to achieve, but you will find that your code can become complex quite quickly, so look for common functionality, and start off as simple as possible ! To start of with, just try and see if the human player has 3 pieces in a line in the first row. Then, test your program, and put 3 human player pieces into the top row and ensure that this function determines a win. Then, expand this code to work with all rows, and test this works. Then, write further code to determine if the human player has 3 pieces in a line in the first column, and test this works. Then extend this to all columns, and test this works. Next, add in diagonal checking, and test this. Finally, make the above code generic so you can use it for human and computer pieces, and test this works.
b. If there is no winner, then the function needs to determine if there is a draw. To do this, you should count the number of empty squares in your game?s 3 x 3 grid. If no squares are free, then (because we didn?t find a winner above) we have a draw.
8. A hard function to develop is : Get_Computers_Move. This function will require careful development and testing at each step of the way to ensure that each bit works before moving onto the next. To start with, this function may simply grab the first empty square that it finds in the game grid. You can then add the more advanced movement strategies in piece by piece as you go. Test things out at each stage before you proceed !!
9. As you develop the above functions, you should always keep an eye out for common functionality that can be used by other functions. This common functionality should be moved into its own function to enable other parts of your program to use it as required.
10. Avoid bad programming practices. e.g. Global Variables are bad.
11. Make sure your program exhibits the Quality Program Features. Always comment your code - especially during development - so you will know what you have done and why. The use of Global Constants are highly recommended. Also, the use of Enumerated Types (enums) and Typedefs are also highly recommended, and you should use these wherever appropriate.