/* yz@ai.univ-paris8.fr */
/* gcc -g -Wall life.c -o life -lcurses */

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

const int ROW = 30;
const int COL = 60;

const int DEAD = 0;
const int LIVE = 1;

int main() {
  int cell[ROW][COL], newCell[ROW][COL];
  int i, j;
  int nlive;
  char c;
  
  initscr();
  
  srand(time(NULL));
  
  // initialization
  for(i = 0; i < ROW; i++) {
    for(j = 0; j < COL; j++) {
      cell[i][j] = rand() % 2;
      printw("%c", c = cell[i][j] ? '*' : ' ');
    }
    printw("\n");
  }
  refresh();
  erase();
  
  // generation
  for(;;) {
    for(i = 1; i < ROW-1; i++) {
      for(j = 1; j < COL-1; j++) {
	nlive = cell[i-1][j-1] + cell[i-1][j] + cell[i-1][j+1] + cell[i][j+1]
	  + cell[i+1][j+1] + cell[i+1][j] + cell[i+1][j-1] + cell[i][j-1];
	
	switch(nlive) {
	case 2:
	  newCell[i][j] = cell[i][j];
	  break;
	case 3:
	  newCell[i][j] = LIVE;
	  break;
	default:
	  newCell[i][j] = DEAD;
	}
      }
    }
    
    // update
    for(i = 1; i < ROW-1; i++) {
      for(j = 1; j < COL-1; j++) {
	cell[i][j] = newCell[i][j];
      }
    }
    
    // print
    for(i = 0; i < ROW; i++) {
      for(j = 0; j < COL; j++) {
	printw("%c", c = cell[i][j] ? '*' : ' ');
      }
      printw("\n");
    }
    
    sleep(1);
    refresh();
    erase();
  }
  
  endwin();
  
  return 0;
}
