Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_ROWS 24
#define MAX_COLS 24
#define MAX_GENS 1000000000
#define OCCUPIED 1
#define PRINT_OCCUPIED 'X'
#define VACANT 0
#define PRINT_VACANT ' '
/* First and last rows and first and last columns are "buffer zones" */
typedef int world_t[MAX_ROWS][MAX_COLS];
void Print_instructions(void);
/* Output arg: world, number_of_rows_p, number_of_cols_p */
void Initialize_world(world_t world, int *number_of_rows_p,
int *number_of_cols_p);
/* Output args: number_of_rows, number_of_cols, max_gens_p
* Input/Output arg: world
*/
void Get_user_input(world_t world, int* number_of_rows_p,
int* number_of_cols_p, int *max_gens_p);
/* Input args: min, max */
int Get_int_in_range(int min, int max);
/* Input args: number_of_rows, number_of_cols
* Input/output arg: world
*/
void Get_generation_0(world_t world, int number_of_rows,
int number_of_cols);
/* Input args: number_of_rows, number_of_cols
* Input/output args: world
*/
void Find_next_generation(world_t world, int number_of_rows,
int number_of_cols);
/* Input args: world, number_of_rows, number_of_cols */
void Print_world(world_t world, int number_of_rows,
int number_of_cols);
void Skip_rest_of_line(void);
/* Input args: number_of_rows, number_of_cols, world, row, col
* Return value: Number of cells adjacent to world[row][col]
* that are alive.
*/
int Count_neighbors(int number_of_rows, int number_of_cols,
world_t world, int row, int col);
/*
* Input args: world, number_of_rows, number_of_cols, i, j
* Return value: number of occupants of cell in row i, column j
*/
int Cell_count(world_t world, int number_of_rows, int number_of_cols,
int i, int j);
/* Input arg: world, int number_of_rows, int number_of_cols
* Return value: 1 if there's a living cell. 0 otherwise
*/
int Somethings_alive(world_t world, int number_of_rows,
int number_of_cols);
int main(void) {
world_t world;
int number_of_rows;
int number_of_cols;
int max_gens;
int curr_gen;
Print_instructions();
Initialize_world(world, &number_of_rows, &number_of_cols);
Get_user_input(world, &number_of_rows, &number_of_cols, &max_gens);
curr_gen = 0;
while ( (Somethings_alive(world, number_of_rows, number_of_cols))
&& (curr_gen < max_gens) ) {
Find_next_generation(world, number_of_rows, number_of_cols);
Print_world(world, number_of_rows, number_of_cols);
curr_gen++;
}
printf("Enjoyed life ?\n");
return 0;
} /* main */
void Print_instructions(void) {
printf("Welcome to the game of Life!\n\n");
printf("Life is an artificial world on a rectangular grid: each\n");
printf("square or cell is either alive or vacant. The \n");
printf("configuration of living and vacant cells changes \n");
printf("according to the following rules:\n");
printf("1. Any cell with 0 or 1 neighbor will die from\n");
printf(" loneliness.\n");
printf("2. Any living cell with 2 or 3 neighbors will\n");
printf(" surive into the next generation.\n");
printf("3. Any cell with 4 or more neighbors will die from\n");
printf(" overcrowding.\n");
printf("4. Any vacant cell with exactly 3 neighbors will come\n");
printf(" to life in the next generation.\n");
printf("Updates happen all at once. The next generation of\n");
printf("cells is computed solely on the basis of the current\n");
printf("generation. After the next generation is computed, the\n");
printf("current generation is replaced by the newly computed\n");
printf("generation.\n\n");
} /* Print_instructions */
void Initialize_world(world_t world, int* number_of_rows_p,
int* number_of_cols_p) {
int row, col;
for (row = 0; row < MAX_ROWS; row++)
for (col = 0; col < MAX_COLS; col++)
world[row][col] = VACANT;
*number_of_rows_p = 0;
*number_of_cols_p = 0;
} /* Initialize_world */
void Get_user_input(world_t world, int *number_of_rows_p,
int *number_of_cols_p, int *max_gens_p) {
printf("Please enter the number of rows (max of %d)\n", MAX_ROWS );
*number_of_rows_p = Get_int_in_range(1, MAX_ROWS);
printf("Please enter the number of columns (max of %d)\n",
MAX_COLS);
*number_of_cols_p = Get_int_in_range(1, MAX_COLS);
printf("Please enter the maximum number of generations\n");
*max_gens_p = Get_int_in_range(1, MAX_GENS);
/* Skip the rest of the current line before starting to
* read generation 0 -- there's definitely a newline that hasn't
* been read.
*/
Skip_rest_of_line();
Get_generation_0(world, *number_of_rows_p, *number_of_cols_p);
} /* Get_user_input */
void Get_generation_0(world_t world, int number_of_rows,
int number_of_cols) {
int i, j;
char temp;
printf("Enter the first generation\n");
for (i = 0; i < number_of_rows; i++) {
j = 0;
scanf("%c", &temp);
while ((temp != '\n') && (j < number_of_cols)) {
if (temp == PRINT_OCCUPIED)
world[i][j] = OCCUPIED;
j++;
scanf("%c", &temp);
} /* while */
/* If the current character in temp isn't a newline, then
* there's garbage we need to skip over
*/
if (temp != '\n')
Skip_rest_of_line();
} /* for */
} /* Get_generation_0 */
int Get_int_in_range(int min, int max) {
int temp;
scanf("%d", &temp);
while ( (temp < min) && (temp > max) ) {
printf("Please enter a number >= %d and <= %d\n", min, max);
scanf("%d", &temp);
}
return temp;
} /* Get_int_in_range */
void Skip_rest_of_line(void) {
char temp;
scanf("%c", &temp);
while (temp != '\n')
scanf("%c", &temp);
} /* Skip_rest_of_line */
void Find_next_generation(world_t world, int number_of_rows,
int number_of_cols) {
int row, col;
world_t temp_world;
int neighbor_count;
for (row = 0; row < number_of_rows; row++)
for (col = 0; col < number_of_cols; col++) {
neighbor_count = Count_neighbors(number_of_rows,
number_of_cols, world, row, col);
switch (neighbor_count) {
case 0:
case 1:
temp_world[row][col] = VACANT;
break;
case 2:
temp_world[row][col] = world[row][col];
break;
case 3:
temp_world[row][col] = OCCUPIED;
break;
case 4:
case 5:
case 6:
case 7:
case 8:
temp_world[row][col] = VACANT;
break;
default:
printf("Error! neighbor_count for world");
printf("[%d][%d] = %d\n", row, col,
neighbor_count);
exit(-1);
}
} /* for col */
for (row = 0; row < number_of_rows; row++)
for (col = 0; col < number_of_cols; col++)
world[row][col] = temp_world[row][col];
} /* Find_next_generation */
int Count_neighbors(int number_of_rows, int number_of_cols,
world_t world, int row, int col) {
int i, j;
int count = 0;
for (i = row-1; i <= row+1; i++)
for (j = col-1; j <= col+1; j++)
count = count + Cell_count(world, number_of_rows,
number_of_cols, i, j);
count = count - world[row][col];
return count;
} /* Count_neighbors */
int Cell_count(world_t world, int number_of_rows, int number_of_cols,
int i, int j) {
if ((i < 0) || (i >= number_of_rows) ||
(j < 0) || (j >= number_of_cols))
return 0;
else
return world[i][j];
} /* Cell_count */
void Print_world(world_t world, int number_of_rows,
int number_of_cols) {
int row, col;
int j;
/* Print a line */
for (j = 0; j < MAX_COLS; j++)
printf("-");
printf("\n");
for (row = 0; row < number_of_rows; row++) {
for (col = 0; col < number_of_cols; col++)
if (world[row][col] == OCCUPIED)
printf("%c", PRINT_OCCUPIED);
else
printf("%c", PRINT_VACANT);
printf("\n");
}
} /* Print_world */
int Somethings_alive(world_t world, int number_of_rows,
int number_of_cols) {
int i, j;
for (i = 0; i < number_of_rows; i++)
for (j = 0; j < number_of_cols; j++)
if (world[i][j] == OCCUPIED) return 1;
return 0;
} /* Somethings_alive */