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

时间:2017-06-14 05:38:04

标签: c arrays if-statement conways-game-of-life

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

请遵守谷歌康威的生活游戏规则。

/*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
}

1 个答案:

答案 0 :(得分:0)

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

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

根据printf

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