I'm writing a program of Conway's Game of Life. I think I've figured out most of it but there something wrong with the rules I've set up

for(row=0;row<20;row++) {
		for(col=0;col<21;col++) {
			n=0;
			if (a[row][col]=='*') {
				if(a[row-1][col-1]=='*') {
					n++;
				}
				if(a[row-1][col]=='*') {
					n++;
				}
				if(a[row-1][col+1]=='*') {
					n++;
				}
				if(a[row][col-1]=='*') {
					n++;
				}
				if(a[row][col+1]=='*') {
					n++;
				}
				if(a[row+1][col-1]=='*') {
					n++;
				}
				if(a[row+1][col]=='*') {
					n++;
				}
				if(a[row+1][col+1]=='*') {
					n++;
				}
				}
			
			if(n==2 || n==3) {
				b[row][col]='*';
			}
		}
	}

The code should replace the current value in the array with a * if two or three of its surrounding characters are also a *. the * is placed into a second array and after all rules are completed the b array is copied into the a array and it starts over.

What happens if there is a "*" at row 0? Then wouldn't your code attempt to check row "-1", which doesn't exist? Similarly, if a row is at the end of the array, it looks like your code attempts to check ARRAY_END + 1, which is an index that doesn't exist. Same thing goes for the column.

Ok. The only way i can think of fixing that is to add a row of spaces at the start and end aswell as spaces down each side and chage the values in the for loops to start and end differently. Does that sound like a good idea or is there a simpler way?

Thanks

Wouldn't the first if statement mean that "births" cannot occur. If there is no '*' in the position then there will never be one. I suggest removing the line below:

if (a[row][col]=='*')

You could fix the checking of negative indexes by adding some checks to your code:

if (row > 0 && col > 0 && arr_2d[row-1][col-1]=='#')
            n++;
         if (row > 0 && arr_2d[row-1][col]=='#')
            n++;
         if (row > 0 && col < (ARR_SIZE-1) && arr_2d[row-1][col+1]=='#')
            n++;
         if (row < (ARR_SIZE-1) && col > 0 && arr_2d[row+1][col-1]=='#')
            n++;
         if (row < (ARR_SIZE-1) && arr_2d[row+1][col]=='#')
            n++;
         if (row < (ARR_SIZE-1) && col < (ARR_SIZE-1) && arr_2d[row+1][col+1]=='#')
            n++;
         if (col > 0 && arr_2d[row][col-1]=='#')
            n++;
         if (col < (ARR_SIZE-1) && arr_2d[row][col+1]=='#')
            n++;

The code above presumes everything outside the array is "dead". If live results grow towards the edge of the 2d array this implementation is limiting. You might want to consider dynamic allocation of memory or a toroidal array(bottom wraps to top, left wraps to right).

One easy fix is what you came up with. If you want a 10x10 area, make it 12x12 and the active area is 1-10. Keep all the edge values 0.

Also, rather than that list of if statements, you could use

if a(i,j) = '*'
    for i1 = i-1 to i+1
        for j2 = j-1 to j+1
            if a(i1,j2) = '*'
                n=n+1
if n = 3 or 4  
    b(i,j) = '*'  //3 & 4 takes into account the current position

If you want to dynamically allocate memory to store a 2D array of increasing size there is an implementation in the code below. To shorten the code I have removed any error checking on what calloc returns (should never return NULL).

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

char   **a;
int    i,j;
int    row_size=15;
int    col_size=15;
int    new_row_size=15;
int    new_col_size=15;

void print_array()
{
   for (j=0; j<col_size; j++)
      printf("%c", 175);
   printf("\n");

   for (i=0; i<row_size; i++)
   {
      for (j=0; j<col_size; j++)
         printf("%c", a[i][j]);
      printf("\n");
   }

   fflush(stdout);
}

void free_array()
{
   for (i = 0; i < row_size; i++)
      free(a[i]);
   free(a);
}

void reallocate_array()
{
   char **b;

   b = (char **)calloc(1, (new_row_size * col_size * sizeof(char)));

   for (i = 0; i < new_row_size; i++)
      b[i] = (char *)calloc(1, new_col_size * sizeof(char));

   for (i=0;i<new_row_size;i++) 
   {
      for(j=0;j<new_col_size;j++) 
      {
         if (i>=row_size || j>=col_size)
            b[i][j]=' ';
         else
            b[i][j]=a[i][j];
      }
   }

   free_array();
   a = b;
   row_size = new_row_size;
   col_size = new_col_size;
}

void init_array()
{
   a = (char **)calloc(1, (row_size * col_size * sizeof(char)));

   for (i = 0; i < row_size; i++)
      a[i] = (char *)calloc(1, (col_size * sizeof(char)));

   for (i=0;i<row_size;i++) 
      for(j=0;j<col_size;j++)
         a[i][j]=' ';

   // MY OWN TEST INITIALIZATION BELOW
   a[6][7]='#';
   a[7][7]='#';
   a[8][7]='#';
}

void alter_array()
{
   char **t;
   int  row,col,n;
   bool add_row_top=false;
   bool add_row_bot=false;
   bool add_col_left=false;
   bool add_col_right=false;

   t = (char **)calloc(1, (row_size * col_size * sizeof(char)));

   for (i = 0; i < row_size; i++)
      t[i] = (char *)calloc(1, (col_size * sizeof(char)));

   for (row=0;row<row_size;row++) 
   {
      for(col=0;col<col_size;col++) 
      {
         n=0;
         t[row][col]=' ';

         if (row > 0 && col > 0 && a[row-1][col-1]=='#') 
            n++;
         if (row > 0 && a[row-1][col]=='#') 
            n++;
         if (row > 0 && col < (col_size-1) && a[row-1][col+1]=='#')
            n++;
         if (row < (row_size-1) && col > 0 && a[row+1][col-1]=='#') 
            n++;
         if (row < (row_size-1) && a[row+1][col]=='#')
            n++;
         if (row < (row_size-1) && col < (col_size-1) && a[row+1][col+1]=='#')
            n++;
         if (col > 0 && a[row][col-1]=='#') 
            n++;
         if (col < (col_size-1) && a[row][col+1]=='#')
            n++;

         if(n==2 || n==3)
         {
            t[row][col]='#';
            
            if (row==0)
               add_row_top=true;
            if (row==(row_size-1))
               add_row_bot=true;
            if (col==0)
               add_col_left=true;
            if (col==(col_size-1))
               add_col_right=true;
         }
      }
   }

   new_row_size=row_size;
   new_col_size=col_size;

   if (add_row_top)
      ++new_row_size;
   if (add_row_bot)
      ++new_row_size;
   if (add_col_left)
      ++new_col_size;
   if (add_col_right)
      ++new_col_size;

   for (row=0;row<row_size;row++) 
      for(col=0;col<col_size;col++) 
         a[row][col]=t[row][col];

   for (i = 0; i < col_size; i++)
      free(t[i]);
   free(t);

   if (add_row_top || add_row_bot || add_col_left || add_col_right)
   {
      reallocate_array();

      if (add_row_top)
      {
         for (row=(row_size-1);row>0;row--) 
            for(col=0;col<col_size;col++) 
               a[row][col]=a[row-1][col];

         for(col=0;col<col_size;col++) 
            a[0][col]=' ';
      }
      if (add_col_left)
      {
         for (row=0;row<row_size;row++) 
            for(col=(col_size-1);col>0;col--) 
               a[row][col]=a[row][col-1];

         for (row=0;row<row_size;row++) 
            a[row][0]=' ';
      }
   }
}

int main(int argc, char **argv)
{ 
   init_array();
   print_array();

   for (int i=0; i<12; i++)
   {
      alter_array();
      print_array();
   }
   free_array();
   return(0);
}

thanks for your help but I can't use most of that code as in my class we are restricted on what code we can use by what we have been taught. so if we haven't been taught it we can't use. But thanks anyway, I'll just get help from someone in my class.

thanks for your help but I can't use most of that code as in my class we are restricted on what code we can use by what we have been taught. so if we haven't been taught it we can't use. But thanks anyway, I'll just get help from someone in my class.

You didn't explain the rules of the game that well:

i.e. 2 or 3 surrounding cells need to be living for cell to remain alive AND exactly 3 surrounding cells of a dead cell create a living cell.

The basic code is:

for (row=0;row<20;row++)
{
   for(col=0;col<20;col++)
   {
      n=0;
      //**********************************************
          CALCULATE n HERE (n = number of surrounding live cells)
      **********************************************//

      //initialize next generation to current generation
      b[row][col]=a[row][col];

      if (a[row][col]=='*')         //currently living
      {
          if(n!=2 && n!=3)
             b[row][col]=' ';       // DIE!!!
      }
      else if (n==3)                  //currently dead & 3 live
          b[row][col]='*';          // BORN
   }
}

// Make next generation (b) the current generation (a)
for (row=0;row<20;row++)
   for(col=0;col<20;col++)
      a[row][col]=b[row][col];

I've got the code working. Is there anywhere that could be simpler or is good?

#include <stdio.h>
int row,col,n,count;
int main() {
	char b[20][21];
	char a[20][21]={ /*Initial Grid A*/
		{"**.................."},
		{"**.................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"........***........."},
		{"........*..........."},
		{".........*.........."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
		{"...................."},
	};
	for(row=0;row<20;row++) { /*Intialise Grid B*/
		for(col=0;col<20;col++) {
			b[row][col]=a[row][col];
		}
	}
	while(count==0){ /*Loop*/
		for(row=0;row<20;row++) { /*Print Grid*/
			for(col=0;col<20;col++) {
				printf("%c",a[row][col]);
			}
			printf("\n");
		}
		for(row=0;row<20;row++) { /*Rules*/
			for(col=0;col<20;col++) {
				n=0;
				if(a[row-1][col-1]=='*') {
					n++;
				}
				if(a[row-1][col]=='*') {
					n++;
				}
				if(a[row-1][col+1]=='*') {
					n++;
				}
				if(a[row][col-1]=='*') {
					n++;
				}
				if(a[row][col+1]=='*') {
					n++;
				}
				if(a[row+1][col-1]=='*') {
					n++;
				}
				if(a[row+1][col]=='*') {
					n++;
				}
				if(a[row+1][col+1]=='*') {
					n++;
				}
				if(a[row][col]=='*') {
					if(n==2 || n==3){
						b[row][col]='*';
					}else{
						b[row][col]='.';
					}
				}
				if(a[row][col]=='.' && n==3) {
					b[row][col]='*';
				}
			}
		}
	for(row=0;row<20;row++) { /*Copy B into A*/
		for(col=0;col<20;col++) {
			a[row][col]=b[row][col];
			}
		}
		printf("Press 0 to continue to next generation: "); /*Ask user to continue*/
		scanf("%d",&count);
		printf("\n\n");
	}
}

Thanks

This article has been dead for over six months. Start a new discussion instead.