简体   繁体   中英

Accessing out of bounds cells in a 2D array

I can't really see what's wrong with my check neighbors function in my game of life. It checks all the 8 neighbours then depending on the living count assigns the cell being checked to living or dead, then updates the board.

void check_neighbours (int board[][COL])

{

int living = 0, i, j, k, l;
int new_board[ROW][COL];

for (i = 0; i < ROW; i++)
    {
    for (j = 0; j < COL; j++)
        {
        if ((board[i + 1 % ROW][j % COL]) == '#')
            {
                living++;
            }
        if ((board[i - 1 % ROW ][j % COL]) == '#')
            {
                living++;
            }
        if ((board[i % ROW][j + 1 % COL]) == '#')
            {
                living++;
            }
        if ((board[i % ROW][j - 1 % COL]) == '#')
            {
                living++;
            }
        if ((board[i + 1 % ROW][j + 1 % COL]) == '#')
            {
                living++;
            }
        if ((board[i - 1 % ROW ][j + 1 % COL ]) == '#')
            {
                living++;
            }
        if ((board[i + 1 % ROW ][j - 1 % COL ]) == '#')
            {
                living++;
            }
        if ((board[i - 1 % ROW ][j - 1 % COL ]) == '#')
            {
                living++;
            }
        if (living == 3)
            {
                new_board[i][j] = '#';
            }
        if (living <= 2)
            {
                new_board[i][j] = '-';
        if (living < 3)
            {
                new_board[i][j] = '-';
            }
        }
    }


for (k = 0; k < ROW; k++)                       
    {
    for (l = 0; l < COL; l++)                   
        {
            board[k][l] = new_board[k][l]; 
        }
    }      
}
}

edit: Added parentheses but still prints the same

Try sticking some brackets into your math:

board[(i + 1) % ROW]

is much safer than

board[i + 1 % ROW]

Isn't this:

board[i + 1 % ROW]

going out of bounds ? Try fixing these issues.

As Paul R suggested, you could use parentheses, in order to catch up with the higher precedence of % operator in comparison to the + operator. So change the code to this:

board[(i + 1) % ROW]

Assuming ROW = 5 and i = 4, you get:

(4 + 1) % 5 = 0 // yeah!

4 + 1 % 5 = 5 // oh dear...

Test edge conditions before doing the living count.

for (i = 0; i < ROW; i++) {
    for (j = 0; j < COL; j++) {
      int living = 0;
      for (int drow = -1; drow <= 1; drow++) {
        int row = i+drow;
        if (row < 0 || row >= ROW) continue;  // over the edge
        for (int dcol = -1; dcol <= 1; dcol++) {
          int col = j+dcol; 
          if (col < 0 || col >= COL) continue;  // over the edge
          if (row==0 && col==0) continue;  
          if (board[row][col] == '#') {
            living++;
          }
        } // endfor dcol
      } // endfor drow

      // This section may need review - GOL rules are unclear in post -see below
      if (living == 3) {
        new_board[i][j] = '#';
      } 
      ...
    } // endfor j
  } // endfor i

If rules follow:

Any live cell with fewer than two live neighbors dies, as if caused by under-population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if by over-population.
Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

     #define ALIVE ('#')
     #define DEAD  ('-')
     #define POP_MIN 2
     #define POP_MAX 3
     #define POP_REPRO 3

     new_board[i][j] = board[i][j];
     if (board[i][j] == ALIVE) {
       if (living < POP_MIN) new_board[i][j] = DEAD;
       else if (living > POP_MAX) new_board[i][j] = DEAD;
     } else {
       if (living == POP_REPRO) new_board[i][j] = ALIVE;
     }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM