#include <stdio.h>
#include <malloc.h>
#define XS 40
#define YS 40
#define getstate(a,b) (((a==-1||b==-1)?0:config[a][b]))

int** config;
int** config2;
int z=0;
char *rep=" 0123456789";

int function(a,b,c,d) {
  int x;
  switch (b) {
  case 0:
    switch (x=a+3*c+9*d) {
    case  0: return 0; break;
    case  1: return 2; break;
    case  2: return 1; break;
    case 21: return 2; break; // µ µ 0 1 -> 1
    case 23: return 1; break; // 1 µ 0 1 -> 0
    case 17: return 2; break; // 1 µ 1 0 -> 1
    case 14: return 2; break; // 1 µ 0 0 -> 1
    case 22: return 2; break; // 0 µ 0 1 -> 1
    case 16: return 1; break; // 0 µ 1 0 -> 0
    case 13: return 1; break; // 0 µ 0 0 -> 0
    default: return 0;
    }
    break;
  case 1: return 1; break; //* 0 * * -> 0
  case 2:
    if (c==1) return 1; else return 2; break;
  }
  return 0;
}

void renderpoint2(i,j,z,s) {
  fprintf(stdout,"%d %d %d %d C\n",i,j,z,s);
}
void renderpoint(ii,ij,iz,s) {
  char *red="1 0 0 .75";
  char *color;
  char *white="1 1 1 .75";
  float i,j,z;
  if (s==1) color=white; else color=red;
  i=(float) ii;
  j=(float) ij;
  z=(float) iz;
  fprintf(stdout,"{ = OFF\n8 6 12\n\t%f %f %f\n",i-0.5,j-0.5,z-0.5);
  fprintf(stdout,"\t%f %f %f\n",i+0.5,j-0.5,z-0.5);
  fprintf(stdout,"\t%f %f %f\n",i+0.5,j+0.5,z-0.5);
  fprintf(stdout,"\t%f %f %f\n",i-0.5,j+0.5,z-0.5);
  fprintf(stdout,"\t%f %f %f\n",i-0.5,j-0.5,z+0.5);
  fprintf(stdout,"\t%f %f %f\n",i+0.5,j-0.5,z+0.5);
  fprintf(stdout,"\t%f %f %f\n",i+0.5,j+0.5,z+0.5);
  fprintf(stdout,"\t%f %f %f\n",i-0.5,j+0.5,z+0.5);
  fprintf(stdout,"\t4 0 1 2 3 %s\n",color);
  fprintf(stdout,"\t4 4 5 6 7 %s\n",color);
  fprintf(stdout,"\t4 0 4 5 1 %s\n",color);
  fprintf(stdout,"\t4 2 6 7 3 %s\n",color);
  fprintf(stdout,"\t4 0 3 7 4 %s\n",color);
  fprintf(stdout,"\t4 1 2 6 5 %s\n}\n\n",color);
}

void transition() {
  int i,j,a,b,c,d,xm,ym,xp,yp;
  int** tmp;
  for (i=0;i<XS;i++) for (j=0;j<YS;j++) {
    xm=i-1;ym=j-1;
    xp=(i+1==XS?-1:i+1);yp=(j+1==XS?-1:j+1);
    a=getstate(xm,ym);b=getstate(xm,yp);c=getstate(xp,yp);d=getstate(xp,ym);
    config2[i][j]=function(a,b,c,d);
  }
  tmp=config;config=config2;config2=tmp;
}

void render(int **conf){
  int i,j;
  fprintf(stderr,"\e[1;1H----- %2d -----\n",z);
  for (i=0;i<XS;i++) {
    for (j=0;j<YS;j++) {
      if (conf[i][j]!=0) renderpoint(i,j,z,conf[i][j]);
      fputc(rep[conf[i][j]],stderr);
    }
    fputc('\n',stderr);fflush(stderr);
  }
  sleep(1);
}

void initconfig() {
  int i,j;
  config=(int **)calloc(XS,sizeof(int *));
  for (i=0;i<XS;i++) {
    config[i]=(int *)calloc(YS,sizeof(int));
    for (j=0;j<YS;j++) {
    config[i][j]=0;
    }
  }
  config[XS/2][YS/2]=2;
  config2=(int **)calloc(XS,sizeof(int *));
  for (i=0;i<XS;i++) {
    config2[i]=(int *)calloc(YS,sizeof(int));
  }
}

int main() {
  initconfig();
  fprintf(stdout,"LIST\n");
  for (z=0,render(config);z<XS/2;z++,render(config))
    transition();
  return 0;
}


