Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

I need to code functions for a gomoku game.

+4 votes
asked Nov 3, 2022 by An Nguyen (270 points)
I need to finish the code below for a gomoku game (tic tac toe but you need 5 in a row to win, and in a 15x15 table) by writing the functions: makeMove to check if the move is valid and if so, make the move, hasWon to check if either of the player has won the game, and displayHistory to display all the moves played and go forward/backward to see the next/previous moves. I'm new to programming and it's quite overwhelming for me, and it's due on 26 November, so I would appreciate any kind of help or suggestions.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MAX_SIZE 15

const char HORZ = 196;
const char VERT = 179;
const char TL   = 218;
const char TM   = 194;
const char TR   = 191;
const char BL   = 192;
const char BM   = 193;
const char BR   = 217;
const int numW  = 3;             // Width for writing out an integer
const int charW = 1;             // Width for writing out a character
const int numPerLine = 15;
const char VERT_START = 195;
const char VERT_END = 180;
const char VERT_MID = 197;
const char* inputCommand = "Previous move/Next move/Stop [p/n/s]: ";
const char* endOfHistory = "This is the end of the match.\nPrevious move/Next move/Stop [p/n/s]: ";
const char* startOfGame = "This is the start of the match.\nPrevious move/Next move/Stop [p/n/s]: ";
const char* invalidInput = "Illegal input, please try again: ";

enum Stone {NA, X, O}; //NA = 0; X = 1; O = 2

struct Move {
    int row;
    int col;
    enum Stone stone;
};

static char* lineString( char left, char mid, char right, char horz, int wcell, int ncell ) {
    static char result[100];
    strcpy(result, "");
    char cell[10];
    for(int i = 0; i < wcell; i++){
        cell[i] = horz;
    }
    cell[wcell] = '\0';
    strncat(result,&left,1);
    char cellMid[20];
    strcpy(cellMid, cell);
    strncat(cellMid, &mid,1);
    for ( int i = 0; i < ncell - 1; i++ )
        strcat(result, cellMid);
    char cellRight[20];
    strcpy(cellRight, cell);
    strncat(cellRight, &right,1);
    strcat(result, cellRight);
    return result;
}

void displayBoard(enum Stone arr[][15], int size) {
    //UPPERLINE
    printf("   ");
    for(int i = 0; i < size; i++) {
        printf("  %c ", (char)(i + 'a'));
    }
    printf("\n");
    printf("   %s\n", lineString( TL, TM, TR, HORZ, 3, numPerLine ));

    //MIDDLE
    for(int i = 0; i < size; i++) {
        printf("%2d %c", size - i, VERT);
        for(int j = 0; j < size; j++) {
            if(arr[i][j] == NA) printf("   %c", VERT);
            if(arr[i][j] == X) printf(" X %c", VERT);
            if(arr[i][j] == O) printf(" O %c", VERT);
        }
        printf("\n");
        if(i != size - 1) printf("   %s\n", lineString( VERT_START, VERT_MID, VERT_END, HORZ, 3, numPerLine ));
    }

    //UNDERLINE
    printf("   %s\n", lineString( BL, BM, BR, HORZ, 3, numPerLine ));
}

void displayBoardSimple(enum Stone arr[][15], int size) {
    for(int i = 0; i < size; i++){
        for(int j = 0; j < size; j++) {
            printf("%d", arr[i][j]);
        }
    }
    printf("\n");
}

bool makeMove(enum Stone board[][15], int size, char* playerMove, bool isFirstPlayerTurn){
    //BEGIN TODO

    //END TODO
}

bool hasWon(enum Stone board[][15], int size, bool isFirstPlayerTurn) {
    //BEGIN TODO
 
    //END TODO
}

void displayHistory(char* history, int numOfMoves) {
    //BEGIN TODO

    //END TODO
}

void startGame() {
    enum Stone game[15][15];
    for(int i = 0; i < MAX_SIZE; i++) {
        for(int j = 0; j < MAX_SIZE; j++) {
            game[i][j] = NA;
        }
    }
    displayBoard(game, MAX_SIZE);
    char playerMove[50];
    bool player1Turn = true;
    printf("Player 1 turn: ");
    while(true) {
        scanf("%s", playerMove);
        if(strcmp(playerMove,"ff") == 0) {
            printf("%s", ((player1Turn) ? "Player 2 won " : "Player 1 won "));
            break;
        }
        else if(makeMove(game, MAX_SIZE, playerMove, player1Turn)){
            if(hasWon(game, MAX_SIZE, player1Turn)) {
                displayBoard(game, MAX_SIZE);
                printf("%s", ((player1Turn) ? "Player 1 won " : "Player 2 won "));
                return;
            }
            player1Turn = !player1Turn;
            displayBoard(game, MAX_SIZE);
            printf("%s", ((player1Turn) ? "Player 1 turn: " : "Player 2 turn: "));
        } else {
            printf("Illegal move, please try again: ");
        }
    }
}

int main()
{
    printf("Welcome to Gomoku!\n");
    printf("1. Play game\n");
    printf("2. History\n");
    printf("3. Exit\n");
    printf("Please select mode [1/2/3]: ");
    int mode;
    while(true){
        scanf("%d", &mode);
        if(mode == 1) {
            startGame();
            return 0;
        } else if (mode == 2) {
            int numOfMoves;
            printf("Please enter number of moves: ");
            scanf("%d", &numOfMoves);
            char history[700];
            printf("Please enter history: ");
            scanf("%s", history);
            displayHistory(history, numOfMoves);
            return 0;
        } else if (mode == 3) {
            return 0;
        } else {
            int c;
            while ((c = getchar()) != '\n' && c != EOF);
            printf("Invalid mode, please try again: ");
        }
    }

    return 0;
}

1 Answer

0 votes
answered Nov 5, 2022 by Peter Minarik (86,160 points)

Get Started!

This looks like a homework assignment of some kind. You did not include the whole description (e.g. what's the format of the move entered by the player -- I'd assume it's something like "G12").

So here's some guidance:

Implement bool makeMove(enum Stone board[][15], int size, char* playerMove, bool isFirstPlayerTurn)

The board is the play area.

The size tells you that the dimensions of the board (in your case it is 15 x 15)

playerMove is the input coming from the player (e.g. "G12" in my assumed format, please, consult with your assignment description what the expected format is)

isFirstPlayerTurn indicates which player is playing and if you should put an X or an O on the board.

What I don't understand is why a struct Move is defined in the code when it is never referenced anywhere. Is the signature of the makeMove() function (as above) defined by you or by the teacher?

Anyway, what you're supposed to do is parse the playerMove and put an X or O depending on isFirstPlayerTurn on the board.

I don't understand either why the table is displayed as it is. Line 15 on the screen refers to the 0th row in the board array. Strange choice; it makes the code unnecessarily more complex.

Implement bool hasWon(enum Stone board[][15], int size, bool isFirstPlayerTurn)

What you're supposed to do here is look for X or O symbols depending on isFirstPlayerTurn and determine if you can find 5 in a row. Return true if yes, false if no 5-in-a-row was found.

Implement void displayHistory(char* history, int numOfMoves)

I have no idea what this function is supposed to do. It would make sense to display the last numOfMoves moves, but what's with the history parameter?!

You should consult your task's description.

Get Your Hands Dirty With Code

Now, you should have a pretty good idea of what the individual functions should do. Start working on them. If you get stuck, share your code and ask specific questions. Also, sharing the descript of the task would be helpful too.

Good luck!

asked Nov 7, 2022 by An Nguyen (270 points) Thanks for replying!
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...