Table of Contents

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;
}
cs-142/tic-tac-toe.txt · Last modified: 2015/05/26 23:14 by cs142ta
Back to top
CC Attribution-Share Alike 4.0 International
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0