Gomoku Stage 1: Try It Yourself
Test your problem-solving skills in this challenging Gomoku n-player exercise.
We'll cover the following
We want you to make the first attempt at making the game’s basic structure. We are calling it stage 1. It includes the following steps:
- Initializing the game state and displaying the initial grid having all empty spaces
- Displaying the proper message of who’s turn it is
- Taking inputs from the player whose turn it is
- Validating the move
- Updating the board
- Printing the updated board
- Turn change
- Repeating steps 2-7 for the next player
There are no stopping criteria for ending stage 1. The game should allow two players to play turn by turn, infinitely.
Play it
Click the Run button below to play the game. Here, the user should enter the dimension of the board, the number of players, their symbols as the input, and the game will start. One by one, the user may enter coordinates (1 to dim
for rows and columns) to occupy that place. The console will show the updated board accordingly.
Try playing it at least once to understand Stage 1 and what needs to be implemented.
The main flow of stage 1
Below is a step-by-step main flow of stage 1 of Gomoku.
Step 0: dim, Board[][], NOP, ri, ci , NOP, turn,pName[NOP][CAPACITY], pSym[ NOP ] = {‘X’, ‘O’}// Note, we are using NOP in the above memory for allocating pName and pSym before even initializing it (that cannot be possible, hence in actual main-flow, we should declare the two arrays with CAPACITY dimension, this is just to make you understand the flow). Also note, for Stage I, we have not used the variables for stopping the game(in case win/draw).Step 1: init(Board, dim, pName, pSym, NOP, turn)// Initialize the empty board, player names, and their symbols, and turn whichever player wants to play first (we recommend you assign it randomly with one of the player's identities between `NOP` player).Step 2: do{printBoard(Board, dim)// Print the board.Step 3: do{askForMove(ri, ci, pName[turn], pSym)// Ask from user to enter coordinates.Step 4: }while(!isValidMove(ri, ci, Board, dim) );// Check if the coordinates are not valid, then move to step 3 again otherwise, move to the next step.Step 5: updateBoard(Board,dim,ri,ci,pSym[turn])// Here, the control will only come if the user has already given correct and valid coordinates. Update the board (Update does not mean displaying the updated board on the console).Step 6: turnChange(turn, NOP)// Turn change. If the Turn is 1, change it to 2 or vice versa.}Step 7: while (true);// it is an infinite game, and move to step 2 again for the next player.
Implementation playground for stage 1
Write your code here:
#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) { // Write the code here } void printBoard(char Board[][CAPACITY], int dim) { system("clear"); // for clearing the console screen // Write the code here } void askForMove(int& ri, int& ci, char pName[], char pSym) { // Write your code here // NOTE: It should display the player name followed by symbol and prompt for (ri, ci) // subtracting 1 from ri and ci because our row and column indices start from (0,0) // Note that the user will enter from 1 to dimension for both (ri and ci) // but this function must subtract from both so that it is translated onto // the board dimensions } bool isValidMove(int ri, int ci, char Board[][CAPACITY], int dim) { // Write your code here // Validate that move done by the current player is within the range of 0-(dim-1) // and also it should not be the position which is already been occupied return false; } void updateBoard(char Board[][CAPACITY], int dim, int ri, int ci, char pSym) { // Write your code here. // Write on the Board at ri and ci position the currect player's symbol // which is passed } void turnChange(int& turn, int NOP) { // Write your code here // Change the turn by incrementing in turn in a circular fashion e.g. if the // turn is 0 it should become 1 and if it is 1 it should become 2 and so on // but if the number of the players are 2 then there is no turn with value 2 // hence it should become 0 again. } 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)); // So that everytime the game start it should select ideally a random turn char choice; char Board[CAPACITY][CAPACITY]; char pName[2][30]; // or char pName[Max_No_Of_Players][30]; char pSym[2]; int NOP, dim; int turn, ri, ci; cout <<"Initializing..."<<endl; // passing the function arguments in the same // order as the function expects them // 1. Initializing the game state init(Board, dim, pName, pSym, NOP, turn); // 2. Displaying the board // printBoard(----); // Uncomment me and complete it // steps to repeat for each player's turn do { /* Complete the main flow according to this _____________________________________________ 3. i) Displaying the proper message of whose turn it is. ii) Taking inputs from the player whose turn it is. 4. Validating the move. If invalid move, repeat step 3 5. Updating the board. 6. Printing the updated board. 7. Turn Change 8. Repeat steps 3 to 8 for the next player. */ } while(true); return 0; }
Directions to follow
Follow the steps below and write your code in the playground above.
1. Initialization
In this step:
-
We should gather user input including the size of the board (dimension), the number of players, the names of the players, and the symbols for each player.
-
Since it’s the start of the game and no symbols have been placed on the board yet, we initialize the board with only dashes.
-
Additionally, we should randomly assign the value of
turn
to a number between 0 and the number of players minus 1.
Let’s define the following function:
void init(char Board[][CAPACITY], int& dim, char pName[2][30],
char pSym[], int& NOP, int& turn)
Its return type will be void
since it will not return anything.
The following parameters should be passed to the function: the character array Board[][CAPACITY]
, the reference variables int &dim
, int &NOP
and int &turn
, the character arrays for the player names char pName[2][30]
, and the player symbols char psym[]
. Here, CAPACITY
is a macro that has been defined as 100
.
Instruction: Write the init()
function in the playground. You will not be able to test the program until you complete the next step.
2. Displaying the board
Once we’re done with the initialization, the next obvious step would be to print the board on the screen. So, now we print the board on the console.
Let’s create a void
type function called printBoard()
that takes the 2-D board array and the dimension as parameters.
Instruction: Complete the code of printBoard()
and call it just after the init()
function in the main flow (the main()
function) and run your playground.
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.
a. Asking for the move
We can define a function called askForMove()
that returns void
and takes two reference variables (int &ri
and int &ci
) as input. This function will prompt the player with the name pName[]
and symbol pSym
to enter the row and column of their desired move. The function would be written as follows:
void askForMove(int& ri, int& ci, char pName[], char pSym)
b. Checking for invalid input
Keep these considerations in mind when validating the input:
- What if the user enters a row and/or column that isn’t within the board’s dimensions?
- What if the user enters a position that already has a symbol? We obviously wouldn’t want the previous symbol to be overwritten.
Instruction: Implement the function according to the above requirements.
bool isValidMove(int ri, int ci, char Board[][CAPACITY], int dim)
We can ask the user for input inside a do-while
loop, repeatedly prompting them to enter a valid input until they do so.
4. Updating the board
After we’ve collected the input from the user, we need to update the game board with their move. To do this, we can create a function called updateBoard()
that writes the symbol pSym
to the specified position (ri
and ci
) on the board (Board[][CAPACITY]
).
void updateBoard(char Board[][CAPACITY], int dim, int ri, int ci, char 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 define the function turnChange()
that takes two parameters whose turn it is (int &turn
) and the total number of players (int NOP
).
So, the function becomes the following:
void turnChange(int& turn, int NOP)
Instruction: Implement the above six steps and thoroughly test them. The output should match the sample provided at the beginning of the lesson.
The solution for the implementation of stage 1 is provided in the next lesson.