Tic-Tac-Toe

Very basic tic-tac-toe game

// Project 05-05
// Name: Tic-Tac-Toe

// #define DEBUG

#include <iostream>
#include <string>

// For random player selection:
#include <cstdlib>
#include <ctime>

using namespace std;

const int ROWS = 3;
const int COLS = 3;
const int FIELDS = ROWS * COLS;

void runGame();
void initializeGameBoard(string gameBoard[ROWS][COLS]);
void printCurrentBoard(string gameBoard[ROWS][COLS]);
void getUserInput(bool xTurn, string gameBoard[ROWS][COLS]);
bool cellAlreadyOccupied(int row, int col, string gameBoard[ROWS][COLS]);
string getWinner(string gameBoard[ROWS][COLS]);
bool isBoardFull(string gameBoard[ROWS][COLS]);


int main()
{

	cout << "/---------------------------------------------------\\" << endl;
	cout << "|                 Tic-Tac-Toe Game                  |" << endl;
	cout << "|         ================================          |" << endl;
	cout << "| Course:     The Complete C++ Developer Course     |" << endl;
	cout << "| Instructor: John P. Baugh, Ph.D.                  |" << endl;
	cout << "| Student:    Patrick Kox                           |" << endl;
	cout << "\\---------------------------------------------------/" << endl << endl;

	bool playAgain = true;
	char again = 'n';
	while (playAgain) {
		runGame();
		cout << "Play another game? (y/n) ";
		cin >> again;
		cin.get();
		if ((again =='y')||(again == 'Y')) {
			playAgain = true;
		}
		else {
			playAgain = false;
		}
	}


	return 0;
}

void runGame()
{
	string winner = " ";    
	/*!
	blank: s no winner yet
	X: Player X has won
	O: Player O has won
	C: Cat's game (a tie, there is no winner)
	*/

	/*!
	Make a 3 X 3 gameboard
	*/
	string gameBoard[ROWS][COLS];
	string playerOne = "";
	string playerTwo = "";

	cout << "Please enter a name for player one (X): ";
	getline(cin, playerOne);
	cout << "Please enter a name for player two (O): ";
	getline(cin, playerTwo);
	
	/*!
	Initialize all 'fields' of the gameboard with blanks
	*/
	initializeGameBoard(gameBoard);

	// Is it X's turn or not?
	bool xTurn = 0;

	/*!
	Generate a random number between 1 and 2, this is used to select
	a 'Random" player to start the game:
	1: Player X
	2: Player O
	*/
	srand(time(nullptr));
	int randomPlayer = rand() % 2 + 1;
	#ifdef DEBUG
	cout << "Random player number is " << randomPlayer << endl;
	#endif


	if (randomPlayer == 1) {
		xTurn = true;
	}
	else {
		xTurn = false;
	}

	while (!isBoardFull(gameBoard)) {
		printCurrentBoard(gameBoard);
		string winner = getWinner(gameBoard);
		if (winner == "X") {
			cout << playerOne << " has won the game!" << endl;
			break;
		}
		else if (winner == "O") {
			cout << playerTwo << " has won the game!" << endl;
			break;
		}
		if (xTurn == true) {
			xTurn = false;
		}
		else {
			xTurn = true;
		}

		
		// get input from the user:
		getUserInput(xTurn, gameBoard);
	}
}

void initializeGameBoard(string gameBoard[ROWS][COLS])
{	// Set all fields to blank
	#ifdef DEBUG
	cout << "We are initializing the gameBoard..." << endl;
	#endif
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {

			gameBoard[i][j] = ' ';
		}
	}
	#ifdef DEBUG
	cout << "gameBoard initialized..." << endl;
	#endif
}

void printCurrentBoard(string gameBoard[ROWS][COLS])
{
	cout << endl;
	cout << gameBoard[0][0] << " | "  << gameBoard[0][1] << " | " << gameBoard[0][2] << endl;
	cout << "- - - - -" << endl;
	cout << gameBoard[1][0] << " | "  << gameBoard[1][1] << " | " << gameBoard[1][2] << endl;
	cout << "- - - - -" << endl;
	cout << gameBoard[2][0] << " | "  << gameBoard[2][1] << " | " << gameBoard[2][2] << endl;

}

bool isBoardFull(string gameBoard[ROWS][COLS])
{
	int occupiedFields = 0;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			if (gameBoard[ i ][ j ] != " ") {
				occupiedFields++;
			}
		}
	}
	if (occupiedFields == FIELDS) {
		printCurrentBoard(gameBoard);
		cout << "It's a 'cat's game', there is no winner." << endl;
		return true;
	}
	else {
		return false;
	}
}

void getUserInput(bool xTurn, string gameBoard[ROWS][COLS])
{
	int rows = 0;
	int cols = 0;
	char PlayerTurn;
	if (xTurn == 1) {
		PlayerTurn = 'X';
	} else {
		PlayerTurn = 'O';
	}
	bool isValid = false;
	while (!isValid) {
		cout << "It's " << PlayerTurn << "'s turn" << endl;
		cout << "Please enter the row THEN the comumn, each from 0, 1, or 2 separated by a spaces: ";
		cin >> rows >> cols;
		bool occupied = cellAlreadyOccupied(rows, cols, gameBoard);
		if ((rows >= 0) && (rows <= 2) && (cols >= 0) && (cols <= 2)) {
				isValid = true;
				if (occupied) {
					cout << "This cell is already occupied, try another one:" << endl;
					isValid = false;
					printCurrentBoard(gameBoard);
					continue;
				}
				gameBoard[rows][cols] = PlayerTurn;
			} else {
				cout << "Invalid input, please try again: ";
				printCurrentBoard(gameBoard);
			}
		}
	}

bool cellAlreadyOccupied(int rows, int cols, string gameBoard[ROWS][COLS])
{
	if (gameBoard[ rows ][ cols ] != " ") {
		return true;
	}
	else {
		return false;
	}
}
string getWinner(string gameBoard[ROWS][COLS])
{
	string Player = " ";
	for (int i = 0; i <= 1; i++) {
		if (i == 0) {
			Player = "O";
		}
		else {
			Player = "X";
		}
		if (gameBoard[0][0] == Player && gameBoard[0][1] == Player && gameBoard[0][2] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on row 0" << endl;
		#endif
			return Player;
		}
		if (gameBoard[1][0] == Player && gameBoard[1][1] == Player && gameBoard[1][2] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on row 1" << endl;
		#endif
			return Player;
		}
		if (gameBoard[2][0] == Player && gameBoard[2][1] == Player && gameBoard[2][2] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on row 2" << endl;
		#endif
			return Player;
		}
		if (gameBoard[0][0] == Player && gameBoard[1][0] == Player && gameBoard[2][0] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on column 0" << endl;
		#endif
			return Player;
		}
		if (gameBoard[0][1] == Player && gameBoard[1][1] == Player && gameBoard[2][1] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on column 1" << endl;
		#endif
			return Player;
		}
		if (gameBoard[0][2] == Player && gameBoard[1][2] == Player && gameBoard[2][2] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on column 2" << endl;
		#endif
			return Player;
		}
		if (gameBoard[0][0] == Player && gameBoard[1][1] == Player && gameBoard[2][2] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on a diagonal" << endl;
		#endif
			return Player;
		}
		if (gameBoard[2][0] == Player && gameBoard[1][1] == Player && gameBoard[0][2] == Player) {
		#ifdef DEBUG
			cout << "We have a winner on a diagonal" << endl;
		#endif
			return Player;
		}
		 // Player = "O";
	}
	    return " ";
}