Search code examples
cmultidimensional-arrayconways-game-of-life

Incorrect number of neighbours in a 2d char array (C)


I've been developing a program for Game of Life, and I think im nearly there, however my only set back is that the program is incorrectly reading the number of neighbours, thus the output is consequently incorrect.

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

int numRows;
int numColumns;
int steps;

void printGrid(char grid[numRows][numColumns]) {

int i, j;
for(i=0; i<numRows; i++) {
    for(j=0;j<numColumns;j++) {
        printf("%c", grid[i][j]);
        if (j == numRows - 1) {
            printf("\n");
        }
    }
}printf("\n");
}

int neighbourValue(int row, int column, char grid[row][column]) {
if(row < 0 ||
   row > numRows -1 ||
   column < 0 ||
   column > numColumns -1 ||
   grid[row][column] == '.') {
    return 0;
} else {
    return 1;
}
}

int getNeighbourCount(int row, int column, char grid[row][column]) {
int neighbour = 0;

neighbour += neighbourValue(row-1, column-1, grid); // Above Left
neighbour += neighbourValue(row-1, column, grid); // Above
neighbour += neighbourValue(row-1, column+1, grid); // Above Right
neighbour += neighbourValue(row, column-1, grid); // Left
neighbour += neighbourValue(row, column+1, grid); // Right
neighbour += neighbourValue(row+1, column-1, grid); // Below Right
neighbour += neighbourValue(row+1, column, grid); // Below
neighbour += neighbourValue(row+1, column+1, grid); //Below Left

return neighbour;
}

void calculations(int row, int column, char grid[row][column]) {
char grid2[row][column];
int neighbour, x, y;

for(x = 0; x < numRows; x++) {
    for(y = 0; y < numColumns; y++) {
        neighbour = getNeighbourCount(x, y, grid);
        if(neighbour == 3) {
            grid2[x][y] = 'X';
        } else if (neighbour == 2 && grid[x][y] == 'X') {
            grid2[x][y] = 'X';
        } else {
            grid2[x][y] = '.';
        }
    }
} printf("\n %d \n", getNeighbourCount(0,1, grid));

Ive included a little debugging print statement here, that prints out the number of neighbours at (0,1) on the grid for the grid printed above.

for(x = 0; x < numRows; x++) {
    for(y = 0; y < numColumns; y++) {
        grid[x][y] = grid2[x][y];
    }
}
printGrid(grid);
}

int main() {

int counter = 0;

scanf("%d %d %d", &numRows, &numColumns, &steps); //Setting up the array

char grid[numRows][numColumns];

int i, j;
for(i=0; i<numRows; i++) {
    for(j=0;j<numColumns;j++) {
        scanf(" %c", &grid[i][j]);
    }
}
printGrid(grid);

do{
    calculations(numRows, numColumns, grid);
    counter++;
}while(counter < steps);
}

I've included the whole code, but I think the problem arises around neighbourValue, as the boundaries may be wrong. A typical input would be 3 3 3 (row column steps) followed by XXX XXX XXX. Would anyone be able to possibly test it out and see where its going wrong? I've got a sneaking suspicion the position at 0,1 (among other positions, may be 'wrapping' and reading neighbours at the opposite end of the grid.


Solution

  • In OP's code, grid is declared as a variable length 2D array:

    int numRows;      // global variables
    int numColumns;
    // ...
    scanf("%d %d %d", &numRows, &numColumns, &steps);
    char grid[numRows][numColumns];
    

    But its dimensions are correctly passed as parameters only to the calculation function:

    void calculations(int row, int column, char grid[row][column])
    //      this signature ^^      ^^^              ^^^   ^^^^
    // is common to almost all of the OP's functions
    
    calculations(numRows, numColumns, grid);
    //           ^^^^^^^   ^^^^^^ correct parameters, the sizes of the grid
    

    While in the calls of the other functions, the wrong parameters are passed:

    // e.g.
    int neighbourValue(int row, int column, char grid[row][column])
    //                     ^^^      ^^^^^^            ^^^  ^^^^^^
    neighbour += neighbourValue(row-1, column-1, grid); // Above Left
    //                           ^^^     ^^^^   
    

    In those cases, OP should pass the actual size of the grid:

    int neighbourValue(int row, int column, int numColumns, char grid[][numColumns])
    //                                           ^^^^^^^^                  ^^^^^^