Tic-tac-toe (also known as noughts and crosses or Xs and Os) is a simple "paper and pencil" game. Two players alternate turns, with the first player marking an X on a 3-by-3 game board and the second marking an O. The goal is to make three of your marks in a row, blocking and preventing your opponent from doing the same.

You are watching: Tic tac toe game in c++ using array

Tic-tac-toe was one of the first (possibly the first) games used to explore artificial intelligence. As suggested by the Wikipedia link, writing a computer program to play a perfect game is relatively simple (see the section on strategy). However, at this point in our study of C++, we use tic-tac-toe only as a way of demonstrating two-dimensional arrays and how to pass them as function arguments.

The Tic-Tac-Toe Problem

Write a C++ program that allows two players to play tic-tac-toe.

Program Requirements:

Use an array to represent the playing boardInitialize the array to represent an empty boardDisplay the game board prior to every move and at the end of the gameprompt each player to move in their turnThe player moves by entering a row and column number and the program marks the corresponding array element with either an X or an OThe program validates each move by insuring that the row and column are inbounds and that the selected space is empty - if the player enters an invalid move, the program loops until a valid move is enteredAs a special case, if the player enters -1 for either the row or the column, the game endsAfter each move, test to see if there is a winnerIf there is a winner, the program displays the board, announces the winner, and endsDeclare a draw and end when no moves remain

Solutions

Even when a program is small and simple, programmers often have a great deal of flexibility in how they choose to implement its various parts. As the size and complexity increase, so do the number of options. The tic-tac-toe example focuses on just four of those choices to illustrate that some choices only work on some operating systems, and some involve tradeoffs between different parts of the program.

One of the purposes of the tic-tac-toe example is to demonstrate how to pass two-dimensional arrays to functions. That implies that the program must define at least one function beyond main. But functions have value far beyond demonstrating syntax and behavior. Functions help to focus our attention on what needs to be done rather than on how to do it. Functions help us manage the complexity of increasingly large programs: they allow us to focus on one small sub-problem - one that we are more likely to understand in its entirety, from beginning to end - while temporarily ignoring the full problem. Our first choice is how to decompose the tic-tac-toe problem into a set of mutually interoperable functions.

*
Functional decomposition for the tic-tac-toe program. There are many ways to decompose a problem and two experienced software designers may decompose the same problem in different ways. Furthermore, both decompositions may work and may be "good" as judged by some abstract measure. And, even if the decompositions are similar, the function names may not be.mainDefines the board array and other variables, sequences the function calls, and loops until the game endsinit_boardInitializes the game boarddisplayDisplays the game board, including the marks made by the playersget_moveAlternates moves between players and gets the players moves as a row and column numbertest_winCalls test_board to see if either player has won; if a play has won, displays the winner and the final state of the game board and ends the programtest_boardExamines the rows, columns, and diagonals for three of the same marks in a row and returns the winning player, if there is one, as a character: "X" or "O"

The second choice that we explore is how we draw the game board. We play the tic-tac-toe game on a 3×3 board. As we have done all semester, we will make the board using ASCII or text characters. But even within this constraint, we still have a choice to make. As a first choice, we may use the characters "|" and "-" to represent the vertical and horizontal lines and the "+" character to represent the intersection or cross lines. Although this approach works, it doesn"t result in smooth, unbroken lines. A second approach is to use the drawing symbols that are available on some systems as extended ASCII codes.

*

const char VERT = "|";const char HORIZ = "-";const char CROSS = "+";

const char VERT = (char)179;const char HORIZ = (char)196;const char CROSS = (char)197;
(a)(b)(c)
Drawing the tic-tac-toe game board.The tic-tac-toe game board drawn graphically so that the lines are unbroken.Symbolic constants used to draw the game board with ASCII characters. Although these values will work on all computers that support ASCII characters, they produce the broken lines reminiscent of printed characters.Symbolic constants for the extended ASCII drawing characters. Using these characters results in smooth lines that look more like they are drawn rather than printed. However, these characters are not supported by all computers. These values are known to work on Windows computers but may not work on others.Our approach is to define symbolic constants for each set of drawing characters, making switching between the different sets easier.The moves that a player can make at any time during gameplay depends on the previous moves made by both players: once a player makes a mark on one of the nine spaces on the board, that space is no longer available for play. Our tic-tac-toe program will use a two-dimensional array to represent the game board, that is, to store each player"s moves. However, the array may also optionally store the characters needed to divide the board into the nine spaces where the players may make their marks. Our third choice then is how to draw the game board. Our first option is storing the line-drawing characters in the game board array, making the display function quite simple. Our second choice is to store the moves in the array and draw the lines in the display function, making it more complex.

*
*
(a)(b)
Options for representing the moves and the game board. Overall, the size and complexity of both approaches are about the same. Version (a) places the complexity in the init_board function while version (b) shifts the complexity to the display function.Moves and board symbols are stored together in a 2D array. This version has the advantage that the display function is small and simple. However, the init_board function is larger and more complex, and while the size of both versions of test_board is is the same, the for-loops needed in this version are a little more complex.Moves only stored in the 2D array - the board is drawn by separate statements in the display function. This implementation results in a small, simple init_board function, but the display function is much larger and more complex.

See more: How Do Protons Neutrons And Electrons Determine The Properties Of An Atom

The fourth and final choice only applies to the display function needed by the version of the program represented by Figure 3(b), and just shows that a given sub-problem can of often be solved in many ways. (The display function for version (a) is simple and structured very much like the multiplication table introduced in chapter 3.) The fence post problem, also introduced in chapter 3, describes a general problem where a loop must print a repeating pattern. In the tic-tac-toe program, the pattern is ar,0|ar,1|ar,2, where each ar,c is one element of row r of the array, and | is the vertical line that is part of the playing board. Using pseudo code, we can demonstrate three of the possible ways structuring the inner loop of the display function:

for col = 0, 1, and 2 print a if col

print afor col = 1 and 2 print "|" and aprint new linefor col = 0 and 1 print a and "|"print a and new line
Pseudo code solutions for the tic-tac-toe display function. Each row of the 3(b) version of the display function represents an instance of the fence post problem, which can be solved in many ways. For each solution, row (the loop control variable for an outer loop), is held constant at 0, 1, or 2.The fence post problem is more challenging when the number of repetitions is either large, variable, or both. The number of repetitions in each loop is fixed at three, which greatly simplifies the problem. The following versions of the tic-tac-toe program demonstrate just a few of the many choices that computer scientists may make when solving a problem with a program.

Downloadable Code

ViewDownloadComments
ttt1.cppttt1.cppmoves and board characters together in the array (Figure 3(a))
ttt2.cppttt2.cppmoves only in the array (Figure 3(b)); has three versions of the display function:Does not use the fence post problem solutionUsed the fence post solutionUses the fact that the game board has exactly three rows and three columns to eliminate the for-loops altogether
Back |Chapter TOC |Next