Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Game of Life Neighbour Check (easier method possible?)

Tags:

c++

I am trying to make the game of life in c++ at the moment, this is my first C++ exercise ever. I have one question, we need to make some game modes like one is called "torus" where cells that leave the board should re-enter it on the opposite side.

Now, i am checking the neighbours right now. But i am hardcoding it with hell a lot of if clauses, because i tried some for-loops but it did not work.

But is this really the only option? To hardcode every possibility (cells on the left side, on the right side, upper side, lower side etc?

This is a fragment of the code i have for that:

int countNeighboursTorus(int a, int b) {

int living = 0;

// when the starting cell is the one on the upper left (start of the board)
if (a == 0 && b == 0) {

    // cell below
    if (board[a - 1][b] != DEAD) {
        living++;
    }
    // cell right below
    if (board[a + 1][b + 1] != DEAD) {
        living++;
    }
    // cell right
    if (board[a][b + 1] != DEAD) {
        living++;
    }
    // cell above (other side of the board)
    if (board[HEIGHT - 1][b] != DEAD) {
        living++;
    }
    // cell above right (other side of the board)
    if (board[HEIGHT - 1][b + 1] != DEAD) {
        living++;
    }

}

// first edge case (height = 0, width != 0):
else if (a == 0 && b != 0) {
    // cell below
    if (board[a - 1][b] != DEAD) {
        living++;
    }
    // cell right below
    if (board[a + 1][b + 1] != DEAD) {
        living++;
    }
    // cell right
    if (board[a][b + 1] != DEAD) {
        living++;
    }
    // cell left below
    if (board[a + 1][b - 1] != DEAD) {
        living++;
    }
    // cell left
    if (board[a][b - 1] != DEAD) {
        living++;
    }
    // cell left above (other side of the board)
    if (board[HEIGHT - 1][b - 1] != DEAD) {
        living++;
    }
    // cell above (other side of the board)
    if (board[HEIGHT - 1][b] != DEAD) {
        living++;
    }
    // cell above right (other side of the board)
    if (board[HEIGHT - 1][b + 1] != DEAD) {
        living++;
    }
}

return living;

}

One of the for loops i wrote, but did not really work, was the following - the loop counted too many cells all the time. After the loop, all the cells ALWAYS had the dead status because the program always counted more than 3 living cells, even if only 2 cells were living from the start. I hope this explanation is helpful, it is a little bit hard to explain. I made an outprint - "+" - and it usually showed about 5/6 plusses, even if it should only show it twice (two living cells).

// for any other "normal" cases inside of the board:
else if (a != 0 && b != 0 && a < HEIGHT - 1 && b < WIDTH - 1) {
    for (int c = -1; c < 2; c++) {
        for (int d = -1; d < 2; d++) {
            if (!(c == 0 && d == 0)) {
                if (board[a + c][b + d] != DEAD) {
                    living++; 
                }
            }
        }
    }
}

Is there ANY option to simplify that? For instance with loops, like i tried? Or is that the way it should be done? I am really not seeing the light on the end of the tunnel right now. Just so that i know if i am doing this for nothing. I am really having some problems with the C++ syntax because i only did Java for about a year until now, so i am a beginner when it comes to C++. I am grateful for any tips!

like image 684
Calimera Avatar asked Nov 06 '17 14:11

Calimera


People also ask

What counts as a neighbor in game of life?

Neighbors of a cell are cells that touch that cell, either horizontal, vertical, or diagonal from that cell. The initial pattern is the first generation. The second generation evolves from applying the rules simultaneously to every cell on the game board, i.e. births and deaths happen simultaneously.

How do you count your neighbors in game of life C?

Game of life algorithm We count the number of live neighbors in a 3x3 neighbourhood. int neighbors = - a[]; for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) neighbors += a[i,j]; If a cell is alive and surrounded by 2 or 3 neighbors it carries on living, otherwise it dies.


2 Answers

Yes. Use the modulus operator:

Instead of

    if (board[a + 1][b + 1] != DEAD) {

use:

    if (board[(a + 1) % HEIGHT][(b + 1) % WIDTH] != DEAD) {

There is a slight complexity when you doing subtraction (% isn't actually the modulus operation, it's the remainder operation). You don't want to use it on -1 (it will just return -1), so add an additional HEIGHT/WIDTH:

    if (board[(a - 1 + HEIGHT) % HEIGHT][(b - 1 + WIDTH) % WIDTH] != DEAD) {

You can then use the same code for all the cells of the board.

like image 86
Martin Bonner supports Monica Avatar answered Oct 06 '22 16:10

Martin Bonner supports Monica


This line tries to access elements of the matrix that are not in matrix range:

if (board[a + c][b + d] != DEAD) {

Before executing this line you have to check if a + c and b + d are in matrix range, and if they are not what should be done instead. For "torus" requirement I guess "left" and "right" out of range should be replaced with wrapped values, and "top" and "bottom" out of range should be just skipped.

like image 22
Dialecticus Avatar answered Oct 06 '22 16:10

Dialecticus