Tic Tac Toe
Problem
Program Tic-Tac-Toe
At each turn, prompt the user for a 0-based row and column
Game is over when someone gets 3 in a row or no more moves are available
X goes first
Assume valid input, but don’t allow players to overwrite each other
Follow the problem solving steps to design a solution.
Solution
#include <iostream>
#include <string>
using namespace std;
const string X_MARK = "X";
const string O_MARK = "O";
const string NO_MARK = " ";
const int BOARD_DIMENSION = 3;
/*
Initialize a tic tac toe board to contain unmarked spaces
@param board 2d array representing the uninitialized tic tac toe board
*/
void init_board(string board[][BOARD_DIMENSION])
{
for (int row = 0; row < BOARD_DIMENSION; row++)
{
for (int col = 0; col < BOARD_DIMENSION; col++)
{
board[row][col] = NO_MARK;
}
}
}
/*
Print a tic tac toe board to the console
@param board board to print
*/
void display_board(string board[][BOARD_DIMENSION])
{
cout << endl << endl;
for (int row = 0; row < BOARD_DIMENSION; row++)
{
if (row != 0)
{
for (int i = 0; i < BOARD_DIMENSION * 2 - 1; i++)
{
cout << "-";
}
cout << endl;
}
for (int col = 0; col < BOARD_DIMENSION; col++)
{
if (col != 0)
{
cout << "|";
}
cout << board[row][col];
}
cout << endl;
}
}
/*
Check if the current board reflects a winning game for the player represented by "mark"
@param board tic tac toe board
@param mark the mark of the player to check for having won
@param the row and col to check for
@return true if mark has three in a row horizontally, vertically (from given row and column), or diagonally; and false otherwise
*/
bool mark_makes_three_in_a_row(string board[][BOARD_DIMENSION], string mark, int row, int col)
{
// testing horizontal 3 in a row
if (board[row][0] == mark &&
board[row][1] == mark &&
board[row][2] == mark)
{
return true;
}
// vertical
else if (board[0][col] == mark &&
board[1][col] == mark &&
board[2][col] == mark)
{
return true;
}
// backslash diagonal
else if (board[0][0] == mark &&
board[1][1] == mark &&
board[2][2] == mark)
{
return true;
}
// forwardslash diagonal
else if (board[2][0] == mark &&
board[1][1] == mark &&
board[0][2] == mark)
{
return true;
}
return false;
}
int main()
{
// create a new board
string board[BOARD_DIMENSION][BOARD_DIMENSION];
init_board(board);
display_board(board);
// pick who goes first
bool is_x_turn = true;
// var for winner
string winner = "CATS";
bool is_winner = false;
// as long as there's no winner and total moves is less than 9
for (int turn = 0; turn < pow(BOARD_DIMENSION,2) && !is_winner; turn++)
{
// select users mark
string current_players_mark = is_x_turn ? X_MARK : O_MARK;
cout << "Place an " << current_players_mark << endl;
// ask user for 0-based coords
int row, col;
do
{
cout << "Give me a 0-based row, col: ";
cin >> row >> col;
// and keep asking as long as they pick an occupied spot
} while (board[row][col] != NO_MARK);
// fill in mark at coordinates
board[row][col] = current_players_mark;
display_board(board);
// check if it's a win
is_winner = mark_makes_three_in_a_row(board, current_players_mark, row, col);
// if it is a win
if (is_winner)
{
// assign a winner and break
winner = current_players_mark;
}
// otherwise
else
{
// switch turns
is_x_turn = !is_x_turn;
}
}
// declare a winner (if there is one)
cout << "WINNER IS " << winner << endl;
system("pause");
return 0;
}
Back to top