#include <stdlib.h>
#include "agents.h"

#define CYCLES 1024  // maximum number of cycles allowed

// cells' behaviour function
static pmAction_t cell (void *mem)
{
  pmAction_t act;
  int dir, neighbours = 0;  // number of neighbour cells alive
  for (dir=UP ; dir<=DOR ; dir++)
    if (pmldGetSquareState (dir) == OCCUP)  // found a live cell
      neighbours ++;
    else{  // unoccupied cell => try to check if it will be born
      int nbdir, nbneighbours = 0;
      for (nbdir=UP ; nbdir<=DOR ; nbdir++){
	int yrel = pmtDir2y (dir) + pmtDir2y (nbdir);
	int xrel = pmtDir2x (dir) + pmtDir2x (nbdir);
	if (pmlrGetSquareState (yrel, xrel) == OCCUP){
	  if ((nbneighbours == 0) && ((yrel != 0) || (xrel != 0)))
	    break;  // cell processed by another live cell
	  nbneighbours ++;
	}
      }
      if (nbneighbours == 3)  // this cell will be born
	pmldCreateAgent (dir, 1, NORM_PR, 0, NULL, 0, cell);
    }
  if ((neighbours != 2)  && (neighbours != 3))  // the cell will die
    pmlmKillAgent ();
  act.type = STAY;  // cells do not move
  return act;
}

// function called at the end of each cycle, controlling the end of simulation
static int runfunc (void)
{
//  pmSaveChanges ();
  if ((pmgGetCycle () >= CYCLES) || (pmgGetAgentNumber () == 0))
    return STOP;
  return CONT;
}

int main (void)
{
  pmpfAgent af[] = {cell, NULL};
  pmpfSource rf[] = {NULL};
  // init environment
  pmInitSystem (0);
  pmLoadSystem ("methuselah", af, rf);
  // start simulation
  pmRunSystem (runfunc);
  pmEndSystem ();
  return 0;
}
