(Game of Life) How to loop through outer layer of a matrix without checking outside of it, simultaneously checking for neighbors?

寵の児 提交于 2019-12-02 13:01:31

The easiest way to handle this is to add two dummy rows and columns: a row above your matrix, a row below your matrix, a column to the left of your matrix, and a column to the right of your matrix. You set them to DEAD once and for all, and run your loops only on the cells in the original matrix.

Always when you have this kind of check - before indexing into array check whether the indices are within the size of the array on which you are about to index. You have to do that first before indexing into array. Earlier you had undefined behavior due to accessing array index out of bound.

if( (rCell - surroundR) <= rows-1 && (cCell - surroundC)<= cols-1 && (rCell - surroundR)>=0 && (cCell - surroundC)>=0 ) {
   /* then do rest of work */

}

You can easily sell some memory to save time by using an array containing one row on each side with only dead elements, and do the processing only in the inside. The algorithm becomes simpler with less risk of errors, but but whole code must be changed to add 2 lines and 2 rows:

void Neighbours(int rows, 
                int cols, cell world[rows][cols], 
                int neighbors[rows][cols]) {

//Loop through each cell in the matrix. 
for(int rCell = 1; rCell < rows-1; rCell++){   // limit to the interior
  for(int cCell = 1; cCell < cols-1; cCell++) {
     // remaining part of the loops is unchanged

One method is to pad the array with rows and columns of dead cells at the edges of the array.

Another method is to write separate pieces of code:

  • One loop processes interior cells (omitting the edge rows and columns) of the array, checking all neighbors.

  • One loop processes the top row, checking only actual neighbors of cells of the top row. Only cells interior to the row are processed, omitting the corners.

  • Similarly, there is one loop for the bottom row, one for the left column, and one for the right column.

  • The four corners are checked separately.

Although this is more code, it executes fewer checks than one loop checking for each cell. Note that that the loops for the top row and the bottom row may be combined (because they share the column coordinate), and the loops for the left edge and the right edge may be combined.

Additional reductions of the computational load are possible. For example, the counts of living cells in each 3*1 strip in the main array can be cached (in an auxiliary array or simply in variables in a carefully crafted loop) to be reused. Each such strip in the interior of the main array is used three times in counting the 3*3 squares around various cells, so caching their counts can eliminate some repeated work.

(Regarding padding: To use proper C code, you need two columns, one on the left and one on the right. However, if your C implementation supported accessing subarray elements out of bounds as long as the addressed element is in the complete array, or you manually map two dimensions into a one-dimensional array, then one padding column would suffice, since it would be both to the left of the left edge of the array proper and to the right of the right edge.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!