//strangeLife.h
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define N_MAX 65	  // lato della matrice
#define ELEM_RANGE2 2 // concentrazione in matrice di cellule


// prototipi delle funzioni di libreria

void riempi_Matrice(int a[][N_MAX]);

void stampa_Matrice(int a[][N_MAX]);

void aggiorna_Matrice(int a[][N_MAX]);

// segue il codice delle funzioni da portare in libreria

void riempiMatrice(int a[][N_MAX])
{
   int i, j, num_random;
   float temp;
   int n = N_MAX; // per comodita' chiamo n N_MAX
	
   // Genero una sequenza casuale per riempire la matrice
   srand(time(NULL));

   for(i=0;i < n;i=i+1)
   {
      for (j=0;j < n;j=j+1)
      {
         num_random = rand();  // qui genero un numero casuale
         temp =  (num_random * ELEM_RANGE2) / RAND_MAX  ; 
         			
         a[i][j]= (int)floor( temp );  
         // il float ritorna ad essere un intero
         if ( a[i][j] ) 
            a[i][j]=1;
      }
   }
}

void stampa_Matrice(int a[][N_MAX]) // notare che qui non si usa il ;
{
   int i;
   int j;
   int n = N_MAX; // per comodita' chiamo n N_MAX

   //stampo una matrice facendo anche i "bordini"	
   // -------- Quindi una riga  (1)
   // |      |	Un carattere "|" all'inizio ed un "|" alla fine (2)e(3)
   // |      |	idem 
   // --------	Una riga per chiudere (4)

   for(i=0;i < n+2;i=i+1) printf("_");  // (1) una riga lunga quanto una matrice
		
   for(i=0;i < n;i=i+1)
   {
      printf("\n");  // andiamo a capo
      printf("|");   // "|" all'inizio e (2)

      for (j=0;j < n;j=j+1)
      {
         if (a[i][j]==1) 
         {	
            printf("@");
         }
         else
         {
            printf(" ");
         }
      }

      printf("|"); // "|" alla fine e (3)
   }
   printf("\n");   // andiamo a capo e tiriamo la riga
   for(i=0;i < n+2;i=i+1) printf("_");  // (4) una riga lunga quanto una matrice
   printf("\n\n");
}

void aggiorna_Matrice (int a[][N_MAX])
// il codice e'stato volutamente semplificato
{
   int i, j, ki, kj ,tot;

   int n = N_MAX; // per comodita' chiamo n N_MAX
   int stato[N_MAX][N_MAX];

	// FACOLTATIVO:
   // considero anche le cellule nei bordi supponendo che le celle al di fuori 
   // della matrice siano semplicemente vuote.
	
   for(i=0;i < n;i=i+1)
   {
      for (j=0;j < n;j=j+1)
      {
         // ispeziono le 9 celle della matrice 3x3
         // e sottraggo la cella centrale
         tot = 0;
         for (ki=i-1; ki <= i+1;ki=ki+1)
         {
            for (kj=j-1; kj <= j+1;kj=kj+1)
            {
               //escludo le celle che non sono nella matrice
               if ((0 <= ki &&  ki < n) && (0 <= kj && kj < n))
                  tot = tot + a[ki][kj];
            }
         }
         tot = tot - a[i][j] ;  // guardo solo l'intorno
         
         // applico le regole di Conway, (ma sono giuste?)
         if ((a[i][j] == 0) &&  (tot == 3)) 
         {
            stato[i][j] =1;
         } 
         else if ((a[i][j] == 1) &&  ( (tot == 3) || (tot == 2)) )  
         {
            stato[i][j] =1;
         } 
         else 
         {
            stato[i][j] =0;
         }
      }
   }
	
   // copio lo stato sulla matrice a
   for(i=0;i < n;i=i+1)
   {
      for (j=0;j < n;j=j+1)
      {
         a[i][j] = stato[i][j];
      }
   }
}