< Previous | Contents | Next >
This function receives a board and returns the winner. There are four possible values for a winner. The function will return either X or O if one of the players has won. If every square is filled and no one has won, it returns TIE. Finally, if no one has won and there is at least one empty square, the function returns NO_ONE.
char winner(const vector<char>& board)
{
// all possible winning rows
const int WINNING_ROWS[8][3] = { {0, 1, 2},
{3, 4, 5},
{6, 7, 8},
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
{0, 4, 8},
{2, 4, 6} };
The first thing to notice is that the vector that represents the board is passed through a constant reference. This means that the vector is passed efficiently; it is not copied. It also means that the vector is safeguarded against any change.
In this initial section of the function, I define a constant, two-dimensional array of ints called WINNING_ROWS, which represents all eight ways to get three in a row and win the game. Each winning row is represented by a group of three numbers—three board positions that form a winning row. For example, the group {0, 1, 2} represents the top row—board positions 0, 1, and 2. The next
group, {3, 4, 5}, represents the middle row—board positions 3, 4, and 5. And so on... .
Next I check to see whether either player has won.
212 Chapter 6 n References: Tic-Tac-Toe
const int TOTAL_ROWS = 8;
// if any winning row has three values that are the same (and not EMPTY),
// then we have a winner
for(int row = 0; row < TOTAL_ROWS; ++row)
{
if ( (board[WINNING_ROWS[row][0]] != EMPTY) && (board[WINNING_ROWS[row][0]] == board[WINNING_ROWS[row][1]]) && (board[WINNING_ROWS[row][1]] == board[WINNING_ROWS[row][2]]) )
{
return board[WINNING_ROWS[row][0]];
}
}
I loop through each possible way a player can win to see whether either player has three in a row. The if statement checks to see whether the three squares in question all contain the same value and are not EMPTY. If so, it means that the row has either three Xs or Os in it, and one side has won. The function then returns the piece in the first position of this winning row.
If neither player has won, I check for a tie game.
// since nobody has won, check for a tie (no empty squares left) if (count(board.begin(), board.end(), EMPTY) == 0)
return TIE;
If there are no empty squares on the board, then the game is a tie. I use the STL count() algorithm, which counts the number of times a given value appears in a group of container elements, to count the number of EMPTY elements in board. If the number is equal to 0, the function returns TIE.
Finally, if neither player has won and the game isn’t a tie, then there is no winner yet. Thus, the function returns NO_ONE.
// since nobody has won and it isn’t a tie, the game ain’t over return NO_ONE;
}