#include <stdio.h>
#include <stdlib.h>

#include <windows.h>
#include <conio.h>

typedef struct pos{
    int val;  		// 0 ou 1
    int color;
}t_pos;

int TX;
int TY;

t_pos**MAT;		//matrices dynamiques de structure
t_pos**SEV;

void    init_matrice        (int tx, int ty);
void    destroy_mat         (void);
int     compte_voisins      (int y, int x);
void    calcul              (void);
void    copie               (void);
void    affiche             (void);
void    gotoxy              (int x, int y);
void    textcolor           (int color);
/******************************************/
int main(int argc, char *argv[])
{
int fin=0;

  printf("Action  : appuyer sur n'importe quelle touche\n"
         "Quitter : q");
  init_matrice(80,23);
  while(fin!='q'){

     if(kbhit()){
        fin=getch();
        affiche();
        calcul();
        copie();
     }
  }
  destroy_mat();

  gotoxy(1,TY+1);
  textcolor(16);
  return 0;
}
/******************************************/
void init_matrice(int tx, int ty)
{
int i ;
    TX=tx;
    TY=ty;
    MAT=(t_pos**)malloc(sizeof(t_pos*)*TY);
    SEV=(t_pos**)malloc(sizeof(t_pos*)*TY);
    for (i=0; i<TY;i++){
        MAT[i]=(t_pos*)malloc(sizeof(t_pos)*TX);
        SEV[i]=(t_pos*)malloc(sizeof(t_pos)*TX);
        memset(MAT[i],0,sizeof(t_pos)*TX);
        memset(SEV[i],0,sizeof(t_pos)*TX);
    }
   MAT[TY/2][TX/2].val=1;
   MAT[TY/2+1][TX/2].val=1;
   MAT[TY/2][TX/2+1].val=1;
   MAT[TY/2+1][TX/2+1].val=1;

   MAT[TY/2][TX/2].color=1;
   MAT[TY/2+1][TX/2].color=1;
   MAT[TY/2][TX/2+1].color=1;
   MAT[TY/2+1][TX/2+1].color=1;
}
/******************************************/
void destroy_mat()
{
int i;
    for (i=0; i<TY; i++){
        free(MAT[i]);
        free(SEV[i]);
    }
    free(MAT);
    free(SEV);
}
/******************************************/
void calcul()
{
int x,y,nb_voisins;

   for (y=1; y<TY-1; y++){
      for (x=1 ;x<TX-1 ;x++){
         nb_voisins=compte_voisins(y,x);
         if (nb_voisins <2 || nb_voisins>3){
            SEV[y][x].val=0;
            SEV[y][x].color = MAT[y][x].color;
         }
         else{
            SEV[y][x].val=1;
            if (MAT[y][x].color<15)
                SEV[y][x].color = MAT[y][x].color+1;
         }
      }
   }
}
/******************************************/
int compte_voisins(int y, int x)
{
int nb=0;

   if (MAT[y][x+1].val==1)
     nb++;
   if (MAT[y-1][x+1].val==1)
     nb++;
   if (MAT[y-1][x].val==1)
     nb++;
   if (MAT[y-1][x-1].val==1)
     nb++;
   if (MAT[y][x-1].val==1)
     nb++;
   if (MAT[y+1][x-1].val==1)
     nb++;
   if (MAT[y+1][x].val==1)
     nb++;
   if (MAT[y+1][x+1].val==1)
     nb++;

   return nb;
}
/******************************************/
void copie()
{
int i,j ;
   for (j=0; j<TY; j++){
      for (i=0 ;i<TX ;i++){
         MAT[j][i]= SEV[j][i];
      }
   }
}
/******************************************/
void affiche()
{
int x,y ;

   for (y=0; y<TY; y++){
      for (x=0 ;x<TX ;x++){
         gotoxy(x+1,y+1);
         textcolor(MAT[y][x].color*16);
         putchar(' ');
      }
   }
}
/******************************************/
void gotoxy(int x, int y)
{
  COORD c;

  c.X = x;
  c.Y = y;
  SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}
/******************************************/
void textcolor (int color)
{
    SetConsoleTextAttribute (GetStdHandle(STD_OUTPUT_HANDLE), color);
}
/******************************************/