I have written a program in C which implements Conway's Game of Life.
Here is my code
#include <stdio.h>
int main(int argc, char *argv[]) {
char field[20][20] = {0}; //game field
char cpy[20][20] = {0}; //copy of game field
int gens; //number of generations
scanf("%d", &gens);//input by user
while(1){ //runs till 'break;'
char c;
scanf(" %c", &c); //read next char
if(c == 'a'){//break at char 'e'
int i,j;
scanf("%d %d",&i,&j);//scan coordinates
field[j][i] = 1; //setting cell to state alive
}else{
break;
}
}
//calculate and print generations
for(int i = 0; i <= gens; i ){
printf("-- Generation: %d\n",i);
//iterating over each cell
for(int k = 0; k < 20;k ){
for(int l = 0; l < 20; l ){
//print current generation
if(field[k][l] == 1){
printf("%c",'#');//alive
}else{
printf("%c",'.');//dead
}
//counting neighbors of field[k][l]
int neighbors = 0;
for(int y = -1; y < 2; y ){
for(int x = -1; x < 2; x ){
if(!(x == 0 && y == 0)){
if( k y < 20 &&
k y >= 0 &&
l x < 20 &&
l x >= 0){
if(field[k y][l x] == 1){
neighbors ;
}
}
}
}
}
//rules
//Any live cell with two or three live neighbours survives.
//Any dead cell with three live neighbours becomes a live cell.
//All other live cells die in the next generation. Similarly, all other dead cells stay dead.
if(field[k][l] == 1 &&
(neighbors == 2 || neighbors == 3)){
cpy[k][l] = 1;
}else if(field[k][l] == 0 &&
neighbors == 3){
cpy[k][l] = 1;
}else if(field[k][l] == 1){
cpy[k][l] = 0;
}
}
printf("\n");
}
//setting gamefield to new generation
for(int a = 0; a < 20; a ){
for(int b = 0; b < 20; b ){
field[a][b] = cpy[a][b];
}
}
}
return 0;
}
The user Input looks like that
3
a 9 9
a 9 10
a 9 11
e
The first number indicates how many generations are to be simulated. After that, the user can set individual cells to 1 by entering the character a
, followed by the x
and y
coordinates of the cell. To determine the end of the input, the user enters the character e
.
As you can see there are 2 arrays in my code one represents the current generation the second represents the next generation.
Just because it interests me, is there a way to implement the whole thing so that you only need one array?
CodePudding user response:
Instead of comparing the original fields, e.g. field[k][l] == 1
you could check it like this: (field[k][l] & 1) == 1
.
Now you are only checking the one-bit of each field.
Then instead of setting a value in the copy like you do (cpy[k][l] = 1
) you would do field[k][l] |= (1 << 1)
a.k.a. set the second bit while merging it with the value of the first bit.
Finally, you would iterate over all fields again, and perform field[k][l] >>= 1
. All the second bits are shifted right, all the first bits are forgotten.
//setting gamefield to new generation
for(int a = 0; a < 20; a ){
for(int b = 0; b < 20; b ){
field[a][b] >>= 1;
}
}