Now that we know how to start and continue the game, let’s implement the second stage, where we decide how and when to stop the game.

  • The game will end in one of two ways: when a player wins or when the game is a draw.
  • We will also implement a tournament format, which allows players to play multiple games with the option to end the tournament after each game.

So let us now incorporate the stopping conditions in our code.

Implementation playground for stage II

Write your code in this playground. The implementation for Stage 1 and the function prototypes for Stage 2 (which will be discussed in the directions section) have already been provided.

#include <iostream>
#include <iomanip>
#include<time.h>

#define CAPACITY 100
using namespace std;

void init(char Board[][CAPACITY], int& dim, char pName[2][30], char pSym[], int&NOP, int& turn, int& winCount);
void printBoard(char Board[][CAPACITY], int  dim);
void userInput(int& ri, int& ci, char pName[], char pSym);
bool validInput(int ri, int ci, char Board[][CAPACITY], int dim);
void updateBoard(char Board[][CAPACITY], int  dim, int ri, int ci, char pSym);
void turnChange(int& turn, int NOP);
// Assume: The above 6 functions implementations are available

bool horizontalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
{
	// Write your code here
}
bool vericalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
{
	// Write your code here
}
bool rightDiagonalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
{
	// Write your code here
}
bool leftDiagonalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
{
	// Write your code here

}
bool isWinHere(char Board[][CAPACITY], int  dim, int winCount, char pSym, int ri, int ci)
{
	// Write your code here
}
bool isWin(char Board[][CAPACITY], int  dim, int winCount, char pSym)
{
	// Write your code here
}
bool isDraw(char Board[][CAPACITY], int dim)
{
	// Write your code here
}

int main()
{
    cout <<"\n\n\t\t\tThe Game of Gomoku...!!!\n\n";
    cout <<"\n\n\t\t\t    Let us play...!\n\n"<<endl;
	srand(time(0));
	char choice;
	char Board[CAPACITY][CAPACITY];
	char pName[2][30];
	char pSym[2];
	int NOP, winCount, dim;
	int turn, ri, ci;
	
	cout <<"Initializing..."<<endl;
	// passing the function arguments in the same 
	  // order as the function expects them
	init(Board, dim, pName, pSym, NOP, turn, winCount);
	// steps to repeat for each player's turn 
	do
	{
		printBoard(Board, dim);
		// do while loop to ensure the input entered is valid 
		do 
		{
		    askForMove(ri, ci, pName[turn], pSym[turn]);
		    if(!isValidMove(ri, ci, Board, dim))
            {		    			
					cout << "Invalid Input" << endl;

			}
		}
        while(!isValidMove(ri, ci, Board, dim));

        // Add code for Stage II: Add winning and draw conditions


		updateBoard(Board, dim, ri, ci, pSym[turn]);
		turnChange(turn, NOP);
	}
	while(true);

	// Add code for Stage II: displaying winner and drawn msg
}


Getting the game to start (Stage 2)

Stage 2 (directions)

The first thing we need to do is to make two functions. First, to decide the winning of the current player. Second, for the drawn case. Let’s make these two functions first and then call them later in the main-flow.

Extending the memory

To declare a game to be over, we need to check if someone has won the game after each turn.

We would need a bool variable called gameOver, which can initially be set to false. We can have a variable called winner set to -1 initially.

Checking for the winner

After displaying the updated board, we can have a function that checks if we have a winner after each turn. Let’s call this function isWin().

What arguments should be included when calling this function to determine if a victory has been achieved?

We would need the following:

  • winCount (to determine if a player has achieved a certain number of consecutive occupied cells, represented by the winCount variable).

  • pSym (to check that particular symbol for winCount condition).

  • Board[][CAPACITY] (on which we are playing) of the dimension dim.

Our function prototype would then be as follows:

bool isWin(char Board[][CAPACITY], int dim, int winCount, char pSym)
The prototype of the isWin() function

The primary win-check logic of the isWin() function would be contained inside the isWinHere() function. This function checks the specified cell of the board for the winning condition.

All of the parameters of this function is similar to its predecessor, with just one addition:

  • It would take the row and column indexes of the cell to check (ri and ci).

The following will be its prototype:

bool isWinHere(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
The prototype of the isWinHere() function

In this function, we’ll be checking 4 directions (why not 8?) for winning, horizontally, vertically, and two diagonally. If any of the conditions are satisfied, the isWinHere() function should return true.

a. Checking win horizontally

Starting with the bool function, horizontalCheck(), we want to check if there are winCount numbers of symbols from left to right.

Now, when checking horizontally, what has changed in terms of rows and columns?

The row remains the same but the number of columns increases.

Let’s create the following function:

bool horizontalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
The prototype of the horizontalCheck() function

Instruction: Write your function implementation in the above playground.

b. Checking win vertically

Our verticalCheck() function is very similar to the function above, except it checks for the winCount number of symbols vertically.

Your function should return true if there are vertical winCount numbers of symbols.

Let’s create the following function:

bool vericalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
The prototype of the verticalCheck() function

Instruction: Write your function implementation in the above playground.

c. Checking win diagonally 1 (from top-left to down-right)

Next, we have the rightDiagonalCheck() function that checks for the winCount number of symbols from left to right diagonally.

Again, this function is also very similar, except here, both the number of rows and columns increase as we go down diagonally.

Let’s create the following function:

bool rightDiagonalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
The prototype of the rightDiagonalCheck() function

Instruction: Write your function implementation in the above playground.

d. Checking win diagonally 2 (from top-right to down-left)

Similarly, the leftDiagonalCheck() function checks for the winCount number of symbols from right to left diagonally.

For this direction, the number of rows increases, and the number of columns decreases as we go down diagonally from right to left.

Let’s create the following function:

bool leftDiagonalCheck(char Board[][CAPACITY], int dim, int winCount, char pSym, int ri, int ci)
The prototype of the leftDiagonalCheck() function

Instruction: Write your function implementation in the above playground.

Checking for the game drawn

Now, let’s check for the other game-stopping conditions to see if the game is drawn or not.

For this, we can simply return false if any one cell is equal to the dash -. If none equals the dash, then we return true.

So, the function prototype would be as follows:

bool isDraw(char Board[][CAPACITY], int dim)
The isDraw() function prototype

Instruction: Write your function implementation in the above playground.

Changes in the main-flow

Let’s incorporate main() to handle these three things one by one.

  • Memory update—we need to save some variables to determine if the game is over, if it has been won, and by whom
  • Winning conditions
  • Match-drawn condition
  • Output appropriate message when the game ends (drawn or win message)
  • Converting the game into a tournament format will allow players to play repeatedly after each game, with the option to continue or end the tournament being prompted after each game