John Horton Conway's Game of Life.

John Horton Conway's Game of Life - simple version

// John Horton Conway's game of Life.

// Michael Ashley / UNSW / 23-May-2003

#define displayWidth   80
#define displayHeight  24

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>

/*
  Each cell has a value of 0 or 1.

  The value of a cell in the next generation depends on its current
  value, and the sum of the values of the neighbouring 8 cells.

  The rules are: 

  Death:    If an occupied cell has 0, 1, 4, 5, 6, 7, or 8 occupied
            neighbours, the organism dies (0, 1 neighbours: of loneliness; 
            4 thru 8: of overcrowding).

  Survival: If an occupied cell has two or three neighbours, the organism
            survives to the next generation.

  Birth:    If an unoccupied cell has three occupied neighbours, it becomes
            occupied.

  These rules can be written in terms of a 2D array, where the first index
  is either 0 or 1 depending on the value of cell under consideration, and
  the second index ranges from 0 to 8 inclusive, and is the number of
  occupied nearest neighbours. The value of the array gives the state of
  the cell in the next generation.
*/

int rule[2][9] = {{0,0,0,1,0,0,0,0,0},
                  {0,0,1,1,0,0,0,0,0}};

/* 
  Now we create a type that contains all the information we need to
  know about the state of the system.
*/

typedef struct {
        unsigned char cell[displayHeight][displayWidth];
} state;

void initialise(state * s) {

    // Initialises the state pointed to by s. This is where we put our
    // initial conditions.

    int i, j;
    struct timeval t;

#if 0     
    // Zero the state.

    for (i = 0; i < displayHeight; i++) {
        for (j = 0; j < displayWidth; j++) {
            s->cell[i][j] = 0;
        }
    }
    
    // A "glider" pattern.
    
    s->cell[40][10] = 1;
    s->cell[41][10] = 1;
    s->cell[42][10] = 1;
    s->cell[42][11] = 1;
    s->cell[41][12] = 1;
#endif
    
    // A random pattern.
    
    // Obtain the time of day, to microsecond resolution.
    
    assert(0 == gettimeofday(&t, NULL)); 
    
    // Use the number of microseconds as the seed for the system
    // random number generator.
    
    srandom(t.tv_usec);
    
    // Here we randomly choose 1/8th of the cells to be alive.

    for (i = 0; i < displayHeight; i++) {
        for (j = 0; j < displayWidth; j++) {
            s->cell[i][j] = random() > 7*(RAND_MAX/8);
        }
    }
    
}

int nearestNeighbours(state *s, int i, int j) {

    // Returns the number of nearest neighbours in the state *s at
    // location [i][j]. We just sum up the neighbouring 8 cells, with
    // careful allowance for hitting the boundary.
    
    return 
        (i > 0               && j > 0              && s->cell[i-1][j-1]) +
        (i > 0               &&                       s->cell[i-1][j]  ) +
        (i > 0               && j < displayWidth-1 && s->cell[i-1][j+1]) +
        (                       j > 0              && s->cell[i]  [j-1]) +
        (                       j < displayWidth-1 && s->cell[i]  [j+1]) +
        (i < displayHeight-1 && j > 0              && s->cell[i+1][j-1]) +
        (i < displayHeight-1 &&                       s->cell[i+1][j]  ) +
        (i < displayHeight-1 && j < displayWidth-1 && s->cell[i+1][j+1]);
}

void evolve(state * prev, state * next) {

    // Evolves state *prev by one generation, returning the result in *next.

    int i, j;

    for (i = 0; i < displayHeight; i++) {
        for (j = 0; j < displayWidth; j++) {
            next->cell[i][j] = 
                rule[prev->cell[i][j]][nearestNeighbours(prev, i, j)];
        }
    }
}

void displayState(state * s) {

    // Displays state *s using ASCII characters.

    int i, j;

    for (i = 0; i < displayHeight; i++) {
        for (j = 0; j < displayWidth; j++) {
            if (s->cell[i][j]) {
                printf("*");
            } else {
                printf(" ");
            }
        }
        printf("\n");
    }
}

int main(int argc, char **argv) {
    state s0, s1;
    int i;

    initialise(&s0);
    
    // To display the state at each generation, uncomment the "displayState"
    // lines. To slow down the display, uncomment the "usleep" lines.

    for (i = 0; i < 50000; i++) {
  //    displayState(&s0);
        evolve(&s0, &s1);
  //    usleep(100000);
  //    displayState(&s1);
        evolve(&s1, &s0);
  //    usleep(100000);
    }
    return 0;
}

And here is an example of a random initial condition, with 1/8th of the cells alive:

*     *  *  *    *    *        *       *  *                     *    *     * *  
   ***               **         *  *   ***  *      *   **      *             *  
 * *              *           *          **           *            **         * 
         *   *   *             *          *    *         *     *        *       
                         **            *    * *             *   *             **
   **    *           *     *     *                      *  **       * * *       
                    *  *                *   **   *                  *  *   *    
 ** **          ** *         * *      *   *                      **          *  
                   *      **        *            *      *       * *  *        * 
         *            *                   *       * **     *** **      *        
         * *           *        *                            *       *          
  *    *      *              *            **           *  *         *           
  * *       *    * *            *   * *                    * **      *          
                      *     *             *  *    *  *   *            *  *  *  *
    **     *   *       *       *  *      *         ** *    * **  *    *     *   
       *  **   *   *          *                     *        *   *   * *   *    
    * *     * *     **     **     *  *  * *   * * *     *          * *    *   **
        *        **** *                 * *    *  *              *          **  
       *   * *        * *  *       *  *        *        *      *  *       *     
           *  *  *    *  **    * *    *           *                    **      *
         *    *                *  *     *              * *       **    *       *
 *   * ***                  *        * *                       * *              
*    *       *   *   *  *        * *                        *      *            
 *                   * *     * **                    *        *             **  
          ** **      **                                   **                **  
          ** **      **                                   **                **  

And this is the result after 100 generations:

                                                                                
          **                                                                    
         *                                                                      
        *                                                                       
         *  *                                                                   
          * **                                                                  
           **                                                                   
 *                                                                              
 *                                                                              
 *                                                                              
                                                                                
                                                                                
                                      ***                                       
                                                                      **        
                    **    *         *     *                     * *   **        
                    **   * *        *     *                      **             
                        *  *        *     *                      *              
                         **                                                     
                                      ***