/* * * CS2123 - C Programming - 10:30 MWF * David John Davis * Chapter 5 - Exercise 18 * * Start Date: October 15, 1996 * Last Changed: October 16, 1996 * * John H. Conway (Scientific American, October 1970, p. 120) invented a game called * Life to model the process of birth, survival, and death. The idea is that * organisms require others in order to survive and procreate but that overcrowding * results in death. This program simulates the game Life. It ask the user for an * integer which it uses to seed a random number generator. This random number * generator is used to generate a random first generation in the game. After this * the game continues for the number of generations defined by N. The games follows * these rules: * * A) Birth Rule: An organism is born into any empty cell that has exactly three * living neighbors. * B) Survival Rule: An organism with either two or three neighbors survives from * one generation to the next. * C) Death Rule: An organism with four or more neighbors dies from overcrowding. * An organism with fewer than two neightbors dies from loneliness. * * This program uses a 10x10 array to represent the environment, and each cell can * have a * to represent a life, or be blank. * */ #include #include #define LIFE_GRID 10 /* Defines the width x height of the arrays used. */ #define N 20 /* Defines the number of generations the program should simulate. */ void load_init(char [LIFE_GRID][LIFE_GRID]); /* Function to setup initial generation. */ void step_generation(char [LIFE_GRID][LIFE_GRID]); /* Function to move forward one generation. */ void print_grid(char [LIFE_GRID][LIFE_GRID]); /* Function to print the array. */ int neighbors(char [LIFE_GRID][LIFE_GRID],int,int); /* Function to figure the number of neighbors for a given cell. */ void copy_array(char [LIFE_GRID][LIFE_GRID],char [LIFE_GRID][LIFE_GRID]); /* Function to copy the contents of one array to another. */ void main(void) { char life[LIFE_GRID][LIFE_GRID]; /* Array used for the simulation. */ int i; unsigned int seed; /* Holds the user entered seed for the random number generater. */ /* Get a unsigned int from the user and use it to seed the random number generator. */ printf("\nPlease enter a postive integer: "); scanf("%u",&seed); srand(seed); /* Print a message to the screen and run load_init to setup the initial generation. */ printf("\n\nGenerating inital grid...\n"); load_init(life); /* Loop to cycle through the different generations. */ for (i=1;i <= N;i++) { printf("\nGeneration: %i\n\n",i); /* Print the generation number on the screen. */ print_grid(life); /* Call print_grid to display the contents of the array. */ step_generation(life); /* Call step_generation to generate the next generation. */ } } /* * load_init() is passed the address of an array of characters. It moves through * each cell in the array, based on a random number provided by the rand() function * it places a * or a space in the given cell of the array. */ void load_init(char A[LIFE_GRID][LIFE_GRID]) { int y,x,z; for (y=0;y < LIFE_GRID;y++) { for (x=0;x < LIFE_GRID;x++) { z=(int)(10.0*rand()/RAND_MAX+1.0); /* Generates a random number between 0 and 10. */ if (z < 5) A[y][x]=' '; else A[y][x]='*'; } } } /* * step_generation() is passed the address of an array of characters. It also sets * up an array of the exact same size as the one whose address was passed. The * function moves through each cell in the array, calling neighbors() to get * the number of neighbors the current cell has. Based on the data from neighbors() * and the rules of Life, it either places a * or space in the corresponding cell * of the second array. Once the function has finished, it calls copy_array() to * copy the contents of the second array into the first array. */ void step_generation(char A[LIFE_GRID][LIFE_GRID]) { int i,j,x; char Z[LIFE_GRID][LIFE_GRID]; /* Defines a second array of the same size as the one being passed. */ for (i=0;i < LIFE_GRID;i++) { for (j=0;j < LIFE_GRID;j++) { x=neighbors(A,i,j); /* Call neighbors() to see haw many neighbors this cell has. */ if (A[i][j] == '*') /* If the cell has an organism in it now. */ { if ((x == 2) || (x == 3)) Z[i][j]='*'; else Z[i][j]=' '; } else /* If the cell is empty. */ { if (x == 3) Z[i][j]='*'; else Z[i][j]=' '; } } } copy_array(Z,A); /* Copy the contents of array Z to array A. */ } /* * print_grid() is passed the address of an array of characters. It moves through this * array printing each charter to the display. It also prints cell numbers across the * top, and along the left side of the output. */ void print_grid(char A[LIFE_GRID][LIFE_GRID]) { int y,x; /* Print column numbers left to right. */ printf(" "); for (x=0;x < LIFE_GRID;x++) printf("%i ",x); printf("\n"); /* Print a row number and the contens of that row. */ for (y=0;y < LIFE_GRID;y++) { printf("%i ",y); for (x=0;x < LIFE_GRID;x++) { printf("%c ",A[y][x]); } printf("\n"); } } /* * neighbors() is passed the address of an array of characters, and two integers. It checks * the positions above, below, to the left & right, and diagnly from the cell specified by * the two itegers passed to the function. For each of the cells checked, ones that contain * a * cause 1 to be added to the sum variable. When finished the function has calculated * the number of neighbors for the given cell in the given array. It return this value to * the calling function. */ int neighbors(char A[LIFE_GRID][LIFE_GRID],int y,int x) { int sum=0,i; /* Check for neighbors to the left, left & above, left & below, of the cell. */ if ((x-1) >= 0) { for (i=y-1;i <= y+1;i++) { if ((i >= 0) && (i < LIFE_GRID)) { if (A[i][x-1] == '*') sum+=1; } } } /* Check for neighbors to the right, right & above, right & below, of the cell. */ if ((x+1) < (LIFE_GRID)) { for (i=y-1;i <= y+1;i++) { if ((i >= 0) && (i < LIFE_GRID)) { if (A[i][x+1] == '*') sum+=1; } } } /* Check for neighbors above the cell. */ if ((y-1) >= 0) { if (A[y-1][x] == '*') sum+=1; } /* Check for neighbors below the cell. */ if ((y+1) < LIFE_GRID) { if (A[y+1][x] == '*') sum+=1; } return sum; /* Return the number of neighbors found to the calling function. */ } /* * copy_array() is passed the address of two character arrays. It makes an exact * copy of the contents of the first array, placing the copy in the second array. */ void copy_array(char A[LIFE_GRID][LIFE_GRID],char B[LIFE_GRID][LIFE_GRID]) { int y,x; for (y=0;y < LIFE_GRID;y++) for (x=0;x < LIFE_GRID;x++) B[y][x]=A[y][x]; }