Search code examples
cconways-game-of-life

Game Of Life does weird things and I don't know whats wrong


So for an assignment I have to code the game of life in C. My problem is, that it calculates the next generation wrong but I have no clue why.

I defined my game struct

typedef struct gameStruct {
    int width;
    int height;
    char* field;
} Game;

For the update I create an temporary array to store the cell states, then iterate over every cell from the actual field. I check the 8 cells next to the current one, check if it's an actual valid neighbor, then get the state of the neighbor cell. After all 8 cells have been checked I set the state for the cell in the temp array. After all cells have been calculated I set field[i] to temp[i].

void update() {
    char* newTemp;  
    newTemp = malloc(sizeof(char) * game.width * game.height);

    for (int y = 0; y < game.height; y++) {
        for (int x = 0; x < game.width; x++) {

            int Index = y * game.width + x;
            int alive_n = 0;
            int dead_n = 0;
            int invalid_n = 0;

            for (int yOff = -1; yOff <= 1; yOff++) {
                for (int xOff = -1; xOff <= 1; xOff++) {
                    if ((xOff == 0 && yOff == 0) || xOff + x < 0 || yOff + y < 0 || x + xOff >= game.width || y + yOff >= game.height) {
                        continue;
                    }
                    else {
                        int newIndex = (y + yOff) * game.width + (x + xOff);
                        switch (game.field[newIndex]) {
                            case '*': alive_n++; break;
                            case ' ': dead_n++; break;
                        default: invalid_n++; break;
                        }
                        
                    }
                }
            }

            char next_state = ' ';
            if (alive_n == 2 || alive_n == 3) {
                next_state = '*';
            }
            else if (alive_n == 0 && dead_n == 3) {
                next_state = '*';
            }
            newTemp[Index] = next_state;        
        }
    }
    for(int i = 0; i < game.width * game.height; i++){
            game.field[i] = newTemp[i];
    }
    free(newTemp);
}

So basically it just does weird stuff that seems totally random. Here is what my result looks compared to an online game of life using the same configuration:

left: my version | right : https://www.dcode.fr/game-of-life

Game Of Life I used for comparison: https://www.dcode.fr/game-of-life

I have no more ideas what the problem could be. Maybe anyone here can help me spot the mistake? Thanks!


Solution

  • Your problem is how you update the cells. The rules are:

    • a live cell dies if it doesn't have 2 or 3 live neighboure;
    • a dead cell comes alive if it has 3 live neighbours.

    That means that you must consider the current state of the cell to determine its next state, but your code doesn't do that. (It also means that it is enough to count the live neighbours.)

    With the rules above, your update code should look like this:

            char next_state = field[Index];
            
            if (next_state == '*') {
                if (alive_n != 2 && alive_n != 3) next_state = ' ';
            } else {
                if (alive_n == 3) next_state = '*';
            }
            
            newTemp[Index] = next_state;