Gomoku Stage 1: Solution
Learn to implement the Gomoku stage 1.
Steps to implement stage 1
1. Initialization
Here’s the function for initialization:
void init(char Board[][CAPACITY], int& dim, char pName[2][30],char pSym[], int&NOP, int& turn, int& winCount){cout << "Dimension: ";cin >> dim;cout << "Win Count: ";cin >> winCount;cout << "# of Players: ";cin >> NOP;for (int i = 0; i < NOP; i++){cout << "Enter player " << i + 1 << "'s name: ";cin >> pName[i]; // or cin.getline(Pname[i], 100)}for (int i = 0; i < NOP; i++){cout << "Enter player " << i + 1 << "'s symbol: ";cin >> pSym[i];}for (int ri = 0; ri < dim; ri++){for (int ci = 0; ci < dim; ci++){Board[ri][ci] = '-';}}// randomly deciding whose return it will beturn = rand() % 2;}
2. Displaying the board
Once we’re done with the initialization, the next step would be to print the board on the screen. So, we print the board on the console.
Here’s the print function:
void printBoard(char Board[][CAPACITY], int dim){system("clear");for (int ri = 0; ri < dim; ri++){for (int ci = 0; ci < dim; ci++){cout << Board[ri][ci] << " ";}cout << endl;}}
Next, in the main()
function, we call the above two functions.
Always pass the arguments to the functions in the same order as the function parameters have been passed.
Here’s what we have so far:
#include <iostream> #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) { cout << "Dimension: "; cin >> dim; cout << "Win Count: "; cin >> winCount; cout << "# of Players: "; cin >> NOP; for (int i = 0; i < NOP; i++) { cout << "Enter player " << i + 1 << "'s name: "; cin >> pName[i]; // or cin.getline(Pname[i]) } for (int i = 0; i < NOP; i++) { cout << "Enter player " << i + 1 << "'s symbol: "; cin >> pSym[i]; } for (int ri = 0; ri < dim; ri++) { for (int ci = 0; ci < dim; ci++) { Board[ri][ci] = '-'; } } turn = rand() % 2; } void printBoard(char Board[][CAPACITY], int dim) { system("clear"); // system("clear"); for (int ri = 0; ri < dim; ri++) { for (int ci = 0; ci < dim; ci++) { cout << Board[ri][ci] << " "; } cout << endl; } } 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); printBoard(Board, dim); }
3. Asking the user to select the cell
Once we have the board in front of us, we can ask the user to select the position to place their symbol.
The user must provide the row and column index for the respective position to place the symbol.
We can make a function, askForMove()
of type void
that takes the two reference variables (int &ri
and int &ci
) to store the row and column of the player char pName[]
, and the player’s respective symbol pSym[turn]
. Our function would then be as follows:
void askForMove(int& ri, int& ci, char pName[], char pSym){cout << pName << "'s Turn to place '" << pSym << " ' (ri, ci): " ;cin >> ri;cin >> ci;// subtracting 1 from ri and ci because our row and column indices start from (0,0)ri--;ci--;}
Checking for invalid input
What if the user enters a row and/or column that isn’t within the board’s dimensions? Orwhat if the user enters a position that already has a symbol? We obviously wouldn’t want the previous symbol to be overwritten.
So this is where we make sure the position selected by all players is valid.
Cell selection within the dimension
For the position to be within the dimension, ri
and ci
need to be greater than or equal to zero and less than or equal to the dimension dim
.
(ri >= 0 && ci >= 0) && (ri <= dim && ci <= dim)
Ensuring the selected position has not been previously selected
For the position to be new and not have been written previously, it needs to be equal to the blank, -
, and not some other symbol.
Board[ri][ci] == '-';
Combined, the bool isValidMove()
function becomes:
bool isValidMove(int ri, int ci, char Board[][CAPACITY], int dim){if ((ri >= 0 && ci >= 0) && (ri <= dim && ci <= dim))return false;if ((Board[ri][ci] == '-'))return false;elsereturn true;}
It can also be efficiently written as follows:
bool isValidMove(int ri, int ci, char Board[][CAPACITY], int dim){return ((ri >= 0 && ci >= 0) && (ri <= dim && ci <= dim) && Board[ri][ci] == '-');}
We can ask for the user’s input inside the do-while
loop so that until a valid input is entered, the user should be asked to enter the valid input.
4. Updating the board
Once we’ve taken the input from the user, we need to write it on the board.
So, we create a function named updateBoard()
that updates the position (at ri
and ci
) with the symbol, pSym
, on the board (Board[][CAPACITY]
).
void updateBoard(char Board[][CAPACITY], int dim, int ri, int ci, char pSym){Board[ri][ci] = pSym;}
5. Displaying the updated board
After updating the board, we print the updated board by calling the printBoard()
method.
6. Changing the turn
Now that one of the players has taken their turn, it’s time to give the turn to another player.
For that, we create the turnChange()
function, which takes two parameters whose turn it is (int& turn
) and the total number of players (int NOP
).
So that the function becomes:
void turnChange(int& turn, int NOP){turn = (turn + 1) % NOP;}
We can keep repeating steps 2-6 to keep playing the game. This is all we need to continue our game.
Complete implementation of stage 1
Look at the code editor below to see all the code we’ve written for stage 1.
#include <iostream> #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 askForMove(int& ri, int& ci, char pName[], char pSym); bool isValidMove(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); 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)); updateBoard(Board, dim, ri, ci, pSym[turn]); turnChange(turn, NOP); } while(true); } void init(char Board[][CAPACITY], int& dim, char pName[2][30], char pSym[], int&NOP, int& turn, int& winCount) { cout << "Dimension: "; cin >> dim; cout << "Win Count: "; cin >> winCount; cout << "# of Players: "; cin >> NOP; for (int i = 0; i < NOP; i++) { cout << "Enter player " << i + 1 << "'s name: "; cin >> pName[i]; // or cin.getline(Pname[i], 100) for full name } for (int i = 0; i < NOP; i++) { cout << "Enter player " << i + 1 << "'s symbol: "; cin >> pSym[i]; } for (int ri = 0; ri < dim; ri++) { for (int ci = 0; ci < dim; ci++) { Board[ri][ci] = '-'; } } turn = rand() % 2; } void printBoard(char Board[][CAPACITY], int Dim) { system("clear"); cout << endl; cout << setw(4) << " "; for( int ci = 0; ci < Dim; ci++) { cout << left << setw(5) << ci+1; } cout << endl; for (int ri = 0; ri < Dim; ri++) { cout << setw(4) << ri+1; for (int ci = 0; ci < Dim; ci++) { cout << Board[ri][ci] << " "; } cout << endl; } } void askForMove(int& ri, int& ci, char pName[], char pSym) { cout << pName << "'s turn to place '" << pSym << "' (ri, ci): " ; cin >> ri; cin >> ci; // subtracting 1 from ri and ci because our row and column indices start from (0,0) ri--; ci--; } bool isValidMove(int ri, int ci, char Board[][CAPACITY], int dim) { return ((ri >= 0 && ci >= 0) && (ri <= dim && ci <= dim) && Board[ri][ci] == '-'); } void updateBoard(char Board[][CAPACITY], int dim, int ri, int ci, char pSym) { Board[ri][ci] = pSym; } void turnChange(int& turn, int NOP) { turn = (turn + 1) % NOP; }