This week, another fairly simple lab (to accommodate the test on Monday), and hopefully one that's a little bit entertaining as well as educational.
Continuing on last week's theme of simple computer games, today we are going to make a tic-tac-toe program. Almost everyone has encountered the game of tic-tac-toe at some point in their childhood, but in case you missed it, here's a link to the Wikipedia Tic-Tac-Toe page that describes the game and it's rules.
Make a lab5 sub-directory of your cs211 directory. Download the file ttt.h, and move it to your lab5 sub-directory. The ttt.h file contains some declares of global variables, and definitions of some utility functions we will be using to make our game work.
Specifically, the ttt.h file contains global declares for each square on a tic-tac-toe board. We label the rows of the board with letters, A, B, and C, and we label the columns with numbers 1, 2 and 3. As a result, the board ends up looking like the following:
In ttt.h, there is a global variable declared as a single character, and initialized to a blank space, for each square with names like A1, A2, and so on to match the board above. These variables will contain either a blank or, as the game goes on, an X, or an O.
The ttt.h file also provides a function called printBoard() which prints the current state of the Tic-Tac-Toe board, along with column and row labels. For instance, at the start of the game, when no moves have been made yet, if you run printBoard(), it will print out the following...
1 2 3 A | | ---+---+--- B | | ---+---+--- C | |
And by the end of the game, running printBoard() will produce something like...
1 2 3 A X | O | X ---+---+--- B O | X | ---+---+--- C X | | O
The infrastructure always assumes that the computer program plays as the "O" player, and that the person running the program plays against the computer as the "X" player.
The ttt.h file also provides a getUserTurn() function. This function will first print a prompt to the terminal window that says Enter a row and column (e.g. A 1) for X : . Then it waits for the user of your program to type a row letter and a column number that represents one of the squares on the board, followed by the enter key. The getUserTurn() function checks to make sure that the user has specified a valid square, and that the chosen square is unoccupied. If so, the function updates the variable associated with that square by putting an 'X' in that variable, and returns. If the selection is not valid, the function tells the user what the problem is, and then prompts again for a valid entry. (To quit the game altogether, the user must type a Ctrl-c when prompted.)
The ttt.h file also provides a function to allow the computer to take a turn called nextOpenTurn(). This function is exceedingly stupid. All it does is to go through the squares sequentially; A1, A2, A3, B1, B2, B3, C1, C2, and C3; until it finds an empty square. When it finds an empty square, it puts an 'O' in that square and returns.
Finally, the ttt.h file contains a function called isWinner(). This function looks at the current state of the board and determines if either 'X' won the game, 'O' won the game, or no more moves can be made but there is no winner (a tie game). The isWinner function returns a single character that can have one of four values:
We will use the C library functions printf and the Tic-Tac-Toe infrastructure so at the top of your ttt.c file, add:
#include <stdio.h> #include "ttt.h"
Note that the stdio.h include uses angle brackets, < and > because stdio.h is a system library include file, but ttt.h uses double quotes because ttt.h is in the current directory. (Or it least it should be if you downloaded and moved it to the lab5 directory as instructed.)
We also need the standard main function, with the standard parameters even though we aren't using any command line parameters this week.
The main function needs to play a game of tic-tac-toe. To do this, create loop that iterates through turns of the game. The following steps need to be included in the loop:
The loop should end when there is a winner or a tie. Print a message that let's us know how things turned out.
Compile and test your game. Can you play until you win? Until the computer wins? Until it's a tie?
The nextOpenTurn() function is not a very good Tic-Tac-Toe player. Can you make it smarter? For instance, can you write a function that checks to see if you already have two out of three squares in a line with 'O's in them, where the third square is blank? If so, you can put an 'O' in that third square and win right away! Or, does your opponent have two out of three squares in a line with an 'X' where the third square is blank? If so, you should put an 'O' in the third square to block your opponent's win.
If you are really into this, it is possible to write a computer player of Tic-Tac-Toe that never loses, even though the human player goes first. (If the human player is smart, every game will end in a tie.) Remember that you will only get extra credit on this lab to replace deductions that you got on this lab, so don't spend too much time on the extra credit part of this problem.
Go to MyCourses, and open the CS-211 page, and choose the "Content" hyperlink on the left list of options. You will see a "Lab 05 Submission" icon to upload your ttt.c file. Make this submission before the due date of Friday, October 6, at 11:59 PM. You may submit as many times as you want before the due date, but only the latest submission will be graded.
This lab is worth 10 points. You will get deductions as follows:
If you received deductions, the CA will check to see if your Computer function is correct, and does a better job than the nextOpenTurn() function provided in ttt.h. If so, you will up to three extra credit points to offset the deduction, depending on how well your Computer function works.