Tic-Tac-Toe Game Demo -- Commentary and Description
Program Description and General Comments
This is a simple tic-tac-toe game demo. It is a one player game so it is
programmed to respond to user moves. The game has 2 difficulty levels. In the
"hard" difficulty level, the AI algorithm is sophisticated enough to prevent
any wins by the human player, so the best that could be hoped for at this level
is a draw game. In the "easy" difficulty level it is possible to achieve a win
if a fork is established in the game. By a fork, I mean a situation in which
two possible moves can achieve a win so the win is unpreventable by the opposing
player since one blocked move will still allow the alternative winning move.
There is a button to restart the game at any stage during the game. There is
also a button to reset the score. The game keeps the score on how many times
the player has won, lost or tied with the computer. A game is not recorded
as being played until it has been completed. The score should reflect this.
Overview of Classes Used In The Program
- Cell
- This class is used to represent the squares on the tic-tac-toe game board.
The data members of this class are:
- Marker:
- This is the marker that is currently marked on the square ("x" or "o")
- Number:
- This is the number of the game square. Squares are numbered from left to
right starting at the top left corner.
- Intersections:
- This value corresponds to the number of winning lines intersecting with
this game square.
- Line
- This class is used to represent any continuous line of 3 squares on the
game board. These include horizontal, vertical as well as diagonal lines.
The data members of this class are:
- SlotFilled:
- This is the number of game squares that are filled for this line.
Any game squares in the line that are filled with the opposing player's marker
will set this value to zero.
- Cells:
- This is an array of 3 Cell class objects that represents some specific sequence
of squares on the game board which forms a winning line.
- Game
- This class is used to represent the entire tic-tac-toe game. This class
will include all the squares on the game board. It will also include all the
winning lines. The data members of this class are:
- Initialized:
- This is a boolean flag which indicates whether or not the class object is
initialized and ready for use.
- Difficulty:
- This data member holds the difficulty level for the game. It could be in
one of either two values: "Hard", "Easy".
- GameOver:
- This flag is set to true if a game has been completed otherwise it is set
to false. Once a game has been completed no further input by the user is allowed
until a new game is started using the "Restart" button. The "Restart" button
resets this flag to false.
- WhoWins:
- This data member stores the marker of the winning side. "x" for human,
"o" for computer.
- Lines:
- This array stores all the winning lines in the game. Each line will store
their respective game squares.
- GamesPlayed:
- This stores the numbers of games completed by the player.
- HumanWins:
- Number of times human player wins.
- HumanLosses:
- Number of times human player losses.
Overview of How The Program Works
The program plays a one player game of tic-tac-toe. At the hardest level it
uses a simple yet effective algorithm for determining the computer's move.
The algorithm written in pseudo-code is:
- Find any lines that is set to win by the computer.
- If such a line is found then complete it by placing a marker on the last
remaining square.
- If no such line is found then find any lines that is set to win by the
human player.
- If such a line is found then block the line by placing a marker on the last
remaining square.
- If no such line is found then find the game square with the best chance of
winning or blocking a winning move from the opposing player. The criteria for
finding such a square involves the number of intersections the square has
with winning lines.
Here is an illustration of Tic-Tac-Toe game board. The winning lines are
colored red, green and blue. We pick the square with the most intersections
with winning lines because having this square occupied with a marker gives
the active player the maximum number of possibilities to complete a line and
therefore win the game while at the same time reduces the number of possible
ways to win by the opposing player.
Although this algorithm is simple, it is effective in preventing all attempts
to win by the human player.At the easiest level, a win is possible by the human
player under some special conditions. The "easy" level algorithm is the same as
the one for the "hard" level except for the last step. For the "easy" level I
simply replaced the last step with:
- Find all available empty squares on the board and randomly pick one to
be marked.
Once the game is completed the winning side will be indicated in the game's
status text box, the score will be changed and display in the score text box
and a message box will be popped out indicating the winner.
The main procedure of this program is: EnterButton
this procedure is passed all input from the user and from here different
member functions of the Game class is called depending on the action to be
taken. The main functions of interest in this program are: Reinitialize,
PlaceMarker, RetrieveLines and PlayTurn.
The following list provides a summary of each of these functions:
- Reintialize
- This function reinitializes the data members in the game object to the
tic-tac-toe game's starting state. This should be done every time the game is
reset via the "Restart" button.
- PlaceMarker
- This function simply places the specified marker ("x" or "o") into the
specified numbered square on the game board.
- RetrieveLines
- This function is used to retrieve data from all the squares on the game
board and set the line objects according to the information contained in
a given square. This needs to be done everytime a move is entered onto the
board.
- PlayTurn
- Tells the computer to play a turn. This will call the appropriate algorithm
to place a marker onto the game board. The "easy" level will not take cell
intersections into account when computing a move.
Summary
As with other demo programs presented on my website, I did not provide an
exhaustive description of this program, but gave a good Top-Level overview
of how things should work within the program. The most important thing about a
program is its architecture and its algorithms, so knowing every tiny detail
of the program is not necessary. This program is actually quite simple and
is lean on features, but it is workable.