Reversi Game –Move Legality Checking in C programming

Sadman Ahmed picture Sadman Ahmed · Nov 5, 2015 · Viewed 8.9k times · Source

The program should ask for user configuration once it initializes the board and then it prints the board using the user configuration. Then it prints the available moves for 'W' & 'B' accordingly. The last step is to ask for a move from the used and if it matches with the available moves printed before then it prints a message of the move is valid, then it prints the board for the last time using the valid move. My code works fine till it prints the configured board, but after then I am getting some weird output here. please help here, thank you. In the following program input should be of the form: U- unoccupied,B- occupied by black,W-occupied by white. here is an example input and expected output: Example

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void boardInitialize(char board[26][26], int n);
void printBoard(char board[26][26], int n);
void checkLegalMovesAvailable(char board[26][26], int N, char colour);
bool positionInBounds(int N, char row, char col);
void printMove(char board[26][26], int n);
void checkLegalInDirection(char board[26][26],int N,char row,char col,char colour,int deltaRow,int deltaCol);
bool checkLegalInMove(char board[26][26], int N, char row, char col, char colour);

int main(void){
    int n;
    char board[26][26];
    printf("Enter the board dimension: ");
    scanf("%d",&n);
    boardInitialize(board,n);
    printBoard(board,n);
    checkLegalMovesAvailable(board,n,'W');
    checkLegalMovesAvailable(board,n,'B');
    printMove(board,n);

    return (EXIT_SUCCESS);
}

//Function to initialize board
void boardInitialize(char board[26][26], int n){
    printf("  ");
    for(int i=0;i<n;i++){
        printf("%c",97+i);
    }
    printf("\n");
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            board[i][j]='U';
        }
    }
    board[(n/2)-1][(n/2)-1]='W';
    board[n/2][n/2]='W';
    board[(n/2)-1][n/2]='B';
    board[n/2][(n/2)-1]='B';
    for(int i=0;i<n;i++){
        printf("%c ",97+i);
        for(int j=0;j<n;j++){
            printf("%c",board[i][j]);
        }
        printf("\n");
    }
}

//Function to print board after configuration
void printBoard(char board[26][26], int n){
    printf("Enter board configuration:");
    printf("\n");
    char color,row,col;
    for(int i=0;(color!='!' && row!='!' && col!='!');i++){
        scanf(" %c%c%c",&color,&row,&col);
            board[row-'a'][col-'a']=color;
    }
    printf("  ");
    for(int i=0;i<n;i++){
        printf("%c",97+i);
    }
    printf("\n");
    for(int i=0;i<n;i++){
        printf("%c ",97+i);
        for(int j=0;j<n;j++){
            printf("%c",board[i][j]);
        }
        printf("\n");
    }   
}

//function to print available moves after configuration
void checkLegalMovesAvailable(char board[26][26], int N, char colour){
    printf("Available moves for %c:\n",colour);
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            if(board[i][j]==colour){
                for(int deltaRow=-1;deltaRow<=1;deltaRow++){
                    for(int deltaCol=-1;deltaCol<=1;deltaCol++){
                        if(deltaRow==0 && deltaCol==0)
                            ;
                        else
                            if(positionInBounds(N,('a'+i+deltaRow), ('a'+j+deltaCol)))
                                checkLegalInDirection(board,N,('a'+i+deltaRow),('a'+j+deltaCol),colour,deltaRow,deltaCol);
                        }
                    }
                }   
            }
        }
    }

//function to check if any move is legal in a specific direction
void checkLegalInDirection(char board[26][26],int N,char row,char col,char colour,int deltaRow,int deltaCol){
    int r=row-'a', c=col-'a',count=0;
    while((positionInBounds(N,'a'+r+(count*deltaRow),'a'+c+(count*deltaCol))) && (board[r+(count*deltaRow)][c+(count*deltaCol)]!=colour) && (board[r+(count*deltaRow)][c+(count*deltaCol)]!='U')){
        count++;
        if((positionInBounds(N,'a'+r+(count*deltaRow),'a'+c+(count*deltaCol))) && (board[r+(count*deltaRow)][c+(count*deltaCol)]=='U')){
        printf("%c%c\n",(row+(count*deltaRow)),(col+(count*deltaCol)));
        break;
        }
    }
}

//function to check if the specified row,col lies within the board dimensions
bool positionInBounds(int N, char row, char col){
    int p=row-'a',q=col-'a';
    if(p>=0 && q>=0 && p<N && q<N)
        return true;
    else
        return false;
}

//function to print board after a legal move 
void printMove(char board[26][26], int n){
    char color,row,col,temp;
    printf("Enter a move:\n");
    scanf(" %c%c%c",&color,&row,&col);
    temp=board[row-'a'][col-'a'];
    board[row-'a'][col-'a']=color;
    if(checkLegalInMove(board,n,row,col,color)){
        printf("  ");
        for(int i=0;i<n;i++){
            printf("%c",97+i);
        }
        printf("\n");
        for(int i=0;i<n;i++){
            printf("%c ",97+i);
            for(int j=0;j<n;j++){
                printf("%c",board[i][j]);
            }
            printf("\n");
        }
    }
    else{
        board[row-'a'][col-'a']=temp;
        printf("  ");
        for(int i=0;i<n;i++){
            printf("%c",97+i);
        }
        printf("\n");
        for(int i=0;i<n;i++){
            printf("%c ",97+i);
            for(int j=0;j<n;j++){
                printf("%c",board[i][j]);
            }
            printf("\n");
        }
    }
}

//function to check if any specific move is legal
bool checkLegalInMove(char board[26][26], int N, char row, char col, char colour){
    int r=row-'a',c=col-'a';
    for(int deltaRow=-1;deltaRow<=1;deltaRow++){
        for(int deltaCol=-1;deltaCol<=1;deltaCol++){
            if(positionInBounds(N,row,col)){
                checkLegalInDirection(board,N,('a'+r),('a'+c),colour,deltaRow,deltaCol);
                printf("Valid move.\n");
                return true;
            }
            else
                printf("Invalid move.\n");
            return false;
        }
    }
}

Answer

Tom Karzes picture Tom Karzes · Nov 5, 2015

Ok, here's one simple observation for you. It looks like you changed checkLegalMovesAvailable so that it now always returns true, correct? So here's a question for you: Does that make sense? If so, then perhaps it shouldn't return anything at all, and its callers should always treat it as if it returned true. If not, then perhaps you should re-think your logic, and figure out under which circumstances it should return true vs. false. Does that make sense?