C:图像(数组)的索引公式,在嵌套for循环中更新索引

C: index formula for images (array), updating index in nested for loop

我的函数接受一个数组(滑翔机或橡子)并在时间为零时准确地描绘它。但是,我的 if/else if 条件语句错误地计算了邻居的数量,或者由于某种原因每个索引都被发送到最后一个 else if(对于远离边缘和角落的索引)。因此,索引 (2,3) 在时间 0 时错误地计算了邻居的数量,索引 (2,3) 在时间 0 +1 时出现,而它应该保持死状态,因为它只有两个邻居。
使用 Torus 拓扑(从上到下和从右到左环绕),这是实际要求:

请Google康威的人生游戏规则。

/*step 1, check whether in array[index] is 0 or 255 (color) and alter auxiliary game[index] to 1 or 0 (dead or alive).  Do this since changes need to happen simultaneously, ie. we cannot incremently change array values without having an effect on later indexes.
step 2, check neighbors for each index of game[] and alter game[] to 1 or 0 depending on rules.  
step 3, based on game[], reset array[] to 255 or 0.*/

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "imgops.h"

/*typedef unsigned __int8 uint8_t; //for Visual Studio*/

void life(uint8_t array[],
    unsigned int cols,
    unsigned int rows)
{
    //must first scan array and set auxiliary array to alive or dead because changes happen simultaneously,
    //ie. if we change index values in array prior to scanning
    unsigned int i = 0, j = 0;

    int left, right, above, below, topleft, topright, botleft, botright;//life deleted
    uint8_t checkPixel;//state is for if alive/dead but now deleted

    uint8_t* game = malloc(cols*rows * sizeof(unsigned int));//allocate memory on heap for auxiliary array

                                                             //index for game array
    unsigned int index = 0;

    for (i = 0; i < cols; i++)//go through array to check 255 or 0 and set game[] to 1 or 0
    {
        for (j = 0; j < rows; j++)
        {
            index = i + (j*cols);
            if (get_pixel(array, cols, rows, i, j)>0)
                game[index] = 1;
            else
                game[index] = 0;
        }
    }


    //Check neighbors 

    for (i = 0; i < cols; i++)
    {
        for (j = 0; j < rows; j++)
        {
            index = i + (j*cols);
            //set values to 0 before checking the 8 neighbors, 1 for true 0 for false
            left = 0;
            right = 0;
            above = 0;
            below = 0;
            topleft = 0;
            topright = 0;
            botleft = 0;
            botright = 0;

            //check top row, bottom row, left column, right column

            //top row but not corners
            if ((i > 0) && (i < cols - 1) && (j == 0))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, i - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, i + 1, j);
                if (checkPixel > 0)//if checkPixel is not black so alive, either 0 or 255
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, rows - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, j + 1);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, i - 1, rows - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, i + 1, rows - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j + 1);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, i + 1, j + 1);
                if (checkPixel > 0)
                {
                    botright = 1;
                }
            }

            //bottom row but not corners
            else if ((i > 0) && (i < cols - 1) && (j == rows - 1))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, i - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, i + 1, j);
                if (checkPixel > 0)
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, j - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, 0);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, i + 1, j - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, i - 1, 0);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, i + 1, 0);
                if (checkPixel > 0)
                {
                    botright = 1;
                }

            }

            //checks left column except corner
            else if ((i == 0) && (j < (rows - 1)) && (j > 0))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, cols - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, i + 1, j);
                if (checkPixel > 0)
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, j - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, j + 1);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, cols - 1, j - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, i + 1, j - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, cols - 1, j + 1);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, i + 1, j + 1);
                if (checkPixel > 0)
                {
                    botright = 1;
                }

            }

            //right column except corners
            else if ((i == cols - 1) && (j < rows - 1) && (j > 0))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, i - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, 0, j);
                if (checkPixel > 0)
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, j - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, j + 1);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, 0, j - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j + 1);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, 0, j + 1);
                if (checkPixel > 0)
                {
                    botright = 1;
                }

            }

            //top left corner
            else if ((i == 0) && (j == 0))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, cols - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, i + 1, j);
                if (checkPixel > 0)//if checkPixel is not black so alive, either 0 or 255
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, rows - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, j + 1);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, cols - 1, rows - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, i + 1, rows - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, cols - 1, j + 1);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, i + 1, j + 1);
                if (checkPixel > 0)
                {
                    botright = 1;
                }
            }

            //bot left corner
            else if ((i == 0) && (j == rows - 1))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, cols - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, i + 1, j);
                if (checkPixel > 0)
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, j - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, 0);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, cols - 1, j - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, i + 1, j - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, cols - 1, 0);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, i + 1, 0);
                if (checkPixel > 0)
                {
                    botright = 1;
                }
            }

            //top right
            else if ((i == cols - 1) && (j == 0))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, i - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, 0, 0);
                if (checkPixel > 0)
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, rows - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, j + 1);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, i - 1, rows - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, 0, rows - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j + 1);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, 0, j + 1);
                if (checkPixel > 0)
                {
                    botright = 1;
                }
            }

            //bottom right
            else if ((i == cols - 1) && (j == rows - 1))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, i - 1, j);
                if (checkPixel > 0)
                {
                    left = 1;
                }

                //checks right
                checkPixel = get_pixel(array, cols, rows, 0, j);
                if (checkPixel > 0)
                {
                    right = 1;
                }

                //checks above
                checkPixel = get_pixel(array, cols, rows, i, j - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }

                //checks below
                checkPixel = get_pixel(array, cols, rows, i, 0);
                if (checkPixel > 0)
                {
                    below = 1;
                }

                //checks topleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }

                //checks topright
                checkPixel = get_pixel(array, cols, rows, 0, j - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }

                //checks botleft
                checkPixel = get_pixel(array, cols, rows, i - 1, 0);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }

                //checks botright
                checkPixel = get_pixel(array, cols, rows, 0, 0);
                if (checkPixel > 0)
                {
                    botright = 1;
                }
            }

            //the other indexes not in corners nor top or bottom rows or very right or left column
            else if ((j != 0) && (j != rows - 1) && (i != 0) && (i != cols - 1))
            {
                //checks left
                checkPixel = get_pixel(array, cols, rows, i - 1, j);
                //printf("%d\n",checkPixel);
                if (checkPixel > 0)
                {
                    left = 1;
                }
                //checks right
                checkPixel = get_pixel(array, cols, rows, i + 1, j);
                if (checkPixel > 0)
                {
                    right = 1;
                }
                //checks above
                checkPixel = get_pixel(array, cols, rows, i, j - 1);
                if (checkPixel > 0)
                {
                    above = 1;
                }
                //checks below
                checkPixel = get_pixel(array, cols, rows, i, j + 1);
                if (checkPixel > 0)
                {
                    below = 1;
                }
                //checks topleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j - 1);
                if (checkPixel > 0)
                {
                    topleft = 1;
                }
                //checks topright
                checkPixel = get_pixel(array, cols, rows, i + 1, j - 1);
                if (checkPixel > 0)
                {
                    topright = 1;
                }
                //checks botleft
                checkPixel = get_pixel(array, cols, rows, i - 1, j + 1);
                if (checkPixel > 0)
                {
                    botleft = 1;
                }
                //checks botright
                checkPixel = get_pixel(array, cols, rows, i + 1, j + 1);
                if (checkPixel > 0)
                {
                    botright = 1;
                }


            }

            //finished scanning neighbors, time to reset values of game[]
            if (game[index] == 0)//for dead cells
            {
                //exactly 3 neignbors revives a dead cell
                if (left + right + above + below + topleft + topright + botleft + botright != 3)
                    game[index] = 0;
                else
                    game[index] = 1;
            }
            else if (game[index] == 1)//for live cells
            {
                //check overcrowding and undercrowding
                if ((left + right + above + below + topleft + topright + botleft + botright == 3)
                    || (left + right + above + below + topleft + topright + botleft + botright == 2))
                {
                    game[index] = 1;
                }
                //if number of neighbors is not 2 or 3
                else
                {
                    game[index] = 0;
                }
            }

            //Reset left, right, above, below, topleft, topright, botleft, botright
            left = 0;
            right = 0;
            above = 0;
            below = 0;
            topleft = 0;
            topright = 0;
            botleft = 0;
            botright = 0;


        }
    }

    //finished setting the game[]
    //alter the main array to set colors according to state
    for (i = 0; i < cols; i++)
    {
        for (j = 0; j < rows; j++)
        {
            index = j + (i*(cols - 1));

            if (game[index] == 1)
            {
                set_pixel(array, cols, rows, i, j, 255);
            }
            else
            {
                set_pixel(array, cols, rows, i, j, 0);
            }
        }
    }

    //end of program
}

malloc 更改为适当的类型(不是 unit8_t),并在填充辅助数组的第一部分使用 get_pixel 而不是公式索引。

在每个 for 循环和 if 语句中编辑公式 index=i + (j*cols) 以确保一致性。

根据 array[].

中的值初始化 game[] 后插入 printf 语句进行调试