My function accepts an array (a glider or acorn) and depicts it accurately at time zero. However, my if/else if conditional statements counts the number of neighbors incorrectly or for some reason every index gets sent to the last else if (for indexes away from edges and corners). Hence the number of neighbors is incorrectly counted at time 0 for index (2,3) which springs to life at time 0 +1 when it should stay dead since it only has two neighbors.
Torus topology is used (wraps around top to bottom and right to left) and here are the actual requirements:
Please Google Conway's game of life for the rules.
/*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
}
Changed the malloc
to the appropriate type (not unit8_t
), and used get_pixel rather than the formula index in the first part of filling the auxiliary array.
Edited formula index=i + (j*cols)
within every for loop and if statement to ensure consistency.
Debugged with printf
statements inserted after initializing the game[]
based on values from array[].