Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check diagonally winner in Connect N using C

Tags:

c

I'm doing the game Connect N using C and I'm having a hard time trying to code an algorithm to check if there is a winner diagonally.

char **BASE;
int piecesToWin, ROWS, COLS;
printf("Enter how many connected pieces to win?: ");
scanf("%d", &piecesToWin);

ROWS = 2 + piecesToWin;
COLS = 3 + piecesToWin;
BASE = (char **) malloc(ROWS * sizeof(char *)); // Allocate the row pointers
for (int i = 0; i < ROWS; i++) //  Allocate each row separately
    BASE[i] = (char *) malloc(COLS * sizeof(char));

// Fill all with space to start
for (int i = 0; i < ROWS; i++)
    for (int j = 0; j < COLS; j++)
        BASE[i][j] = ' ';

After this, I insert a piece to the board and then, I check if there is a winner diagonally.

if (diagAscWin(ROWS, COLS, BASE, piecesToWin, 'X')) {
     printf("X has won!.");
}

if (diagDescWin(ROWS, COLS, BASE, piecesToWin, 'X')) {
     printf("X has won!.");
}

What I have tried to check diagonally:

bool diagAscWin(int ROWS, int COLS, char **BASE, int numToWin, char letter) {
    bool isWinner = false;
    for (int i=3; i<ROWS; i++){
        for (int j=0; j<COLS-3; j++){
            if (BASE[i][j] == letter && BASE[i-1][j+1] == letter && BASE[i-2][j+2] == letter && BASE[i-3][j+3] == letter)
                isWinner = true;
        }
    }

    return isWinner;
}

bool diagDescWin(int ROWS, int COLS, char **BASE, int numToWin, char letter) {
    bool isWinner = false;
    for (int i=3; i<ROWS; i++){
        for (int j=3; j<COLS; j++){
            if (BASE[i][j] == letter && BASE[i-1][j-1] == letter && BASE[i-2][j-2] == letter && BASE[i-3][j-3] == letter)
                isWinner = true;
        }
    }

    return isWinner;
}

These functions are not working. When I have N pieces diagonally, diagAscWin and diagDescWin don't see them and always return false. Also, I'm not sure if I need to initialize i or j with 3 or j<COLS-3. I was trying to replicate a solution from another thread.

Also, I have tried this:

bool diagRightWin(int ROWS, int COLS, char **BASE, int numToWin, char letter) {
    bool isWinner = false;
    int count;
    for (int rowStart = 0; rowStart < ROWS - 4; rowStart++) {
        count = 0;
        int row, col;
        for (row = rowStart, col = 0; row < ROWS && col < COLS; row++, col++) {
            if (BASE[row][col] == letter) {
                count++;
                if (count >= numToWin) isWinner = true;
            } else {
                count = 0;
            }
        }
    }

    return isWinner;
}

bool diagLeftWin(int ROWS, int COLS, char **BASE, int numToWin, char letter) {
    bool isWinner = false;
    int count;
    for (int rowStart = 0; rowStart < ROWS - 4; rowStart++) {
        count = 0;
        int row, col;
        for (row = rowStart, col = 0; row < ROWS && col < COLS; row++, col++) {
            if (BASE[row][col] == letter) {
                count++;
                if (count >= numToWin) isWinner = true;
            } else {
                count = 0;
            }
        }
    }

    return isWinner;
}

These two functions also always return false.

I have tried different logics with no luck. The correct thing is to check how many numToWin pieces are diagonally to say if there is a winner.

I have tried to replicate:

  1. Connect 4 check for a win algorithm
  2. Java: How to check diagonal Connect Four win in 2D array
  3. Javascript - Connect Four game validation
  4. Checking for a line of four (Connect Four in Java)

My goal is to check if there is a winner diagonally (on any direction), having in mind that the board can be big or small, we don't know the size. What we know for sure is the piecesToWin which is the number of pieces that needs to be together to say there is a winner.

like image 495
RRGT19 Avatar asked Dec 03 '25 03:12

RRGT19


1 Answers

The main problem is that you are not exiting the function when you find a match of 4 elements. Also the function looping needs to be modified as shown.

You need two functions to check left diagonal and right diagonal

   /  <-- left diagonal     right diagonal --> \
  /                                             \
 /                                               \
/                                                 \

I have modified the check functions and also added the functionality to check for variable number of elements in a diagonal.

// this function checks diagnonal sloping left "/"
//
bool diagLeftWin(int ROWS, int COLS, char **BASE, int numToWin, char letter) {
    for (int i=0; i<ROWS-numToWin; i++){
        for (int j=0; j<COLS-numToWin; j++){
            char curr = BASE[i][j];  
            if (curr == letter) {
              int k;
              for (k=1; k<numToWin; k++) {
                  if (curr != BASE[i+k][j+k]) {
                     break;
                  }
              }
              if (k == numToWin) {
                  // match found
                  return true;
              }
            }                   
        }
    }
    return false;
}

// this function checks diagnonal sloping right "\"
//
bool diagLeftWin(int ROWS, int COLS, char **BASE, int numToWin, char letter) {
    for (int i=ROWS-numToWin; i>=0; i--){
        for (int j=0; j<COLS-numToWin; j++){
            char curr = BASE[i][j]; 
            if (curr == letter) {
              int k;                
              for (k=1; k<numToWin; k++) {
                  if (curr != BASE[i-k][j+k]) {
                     break;
                  }
              }
              if (k == numToWin) {
                  // match found
                  return true;
              } 
            }                   
        }
    }
    return false;
}

These functions check the entire board every time. You can optimise it to only check around newly added pieces to the board.

like image 155
Rishikesh Raje Avatar answered Dec 04 '25 16:12

Rishikesh Raje



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!