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

#define FieldSize 20
#define TimeMax 20

/************************************************************************
   フィールドの初期化 (ファイルの読み込み)
************************************************************************/
void init_field(int field[FieldSize][FieldSize], char *fname){
  int i,j;
  FILE *fp;

  if((fp=fopen(fname,"r"))==NULL){
    printf("init_field(): Cannot open \"%s\"\n",fname);
    exit(1);
  }

  for(i=0;i<FieldSize;i++){
    for(j=0;j<FieldSize;j++){
      fscanf(fp,"%d ",&field[i][j]);
    }
  }
  fclose(fp);
}

/************************************************************************
   (I,J)の周囲の8マスのうち 状態が1であるものを数える
************************************************************************/
int count(int I, int J, int field[FieldSize][FieldSize]){
  int i,j;
  int i_tmp,j_tmp;
  int sum;
  
  sum=0;
  for(i=-1;i<=1;i++){
    for(j=-1;j<=1;j++){
      /* field[I+i][J+j]の値が1のものを数える
         ただし、I(/J)が 0 や FieldSize-1 のときには注意が必要 */
      /*** この部分を自分で書く ***/
      sum += (  (i||j)&&
                ((i_tmp = I+i) >= 0) && (i_tmp < FieldSize) &&
                ((j_tmp = J+j) >= 0) && (j_tmp < FieldSize) &&
                (field[i_tmp][j_tmp])
             );
    }
  }
  return sum;
}

/************************************************************************
    状態の更新
************************************************************************/
void update_field(int field[FieldSize][FieldSize]){
  int i,j;
  int around; /* 周囲の8マスのうち状態が1であるものの数 */      
  int new_field[FieldSize][FieldSize];  /* 次の状態 */

  for(i=0;i<FieldSize;i++){
    for(j=0;j<FieldSize;j++){
      around=count(i,j,field);
      /* 周囲に3つ1があれば次の状態は1 */
      /*** この部分を自分で書く ***/

      /* 周囲に2つ1があり、現在の状態が1であれば 次の状態は1 */
      /*** この部分を自分で書く ***/

      /* それ以外の場合は 0 */
      /*** この部分を自分で書く ***/
      new_field[i][j] = ( (around|field[i][j]) == 3 );
      
    }
  }

  /* 次の状態の情報(new_field)を fieldにコピー */
  /*** この部分を自分で書く ***/
  (void)memcpy(field,new_field,sizeof(new_field));


}

/************************************************************************
   状態(field)の表示
************************************************************************/
void display(int field[FieldSize][FieldSize]){
  int i,j;

  /* field[i][j]が1であれば■を
                  0であれば□を表示する */
  /*** この部分を自分で書く ***/
  for(i=0;i<FieldSize;i++){
    for(j=0;j<FieldSize;j++){
      printf(field[i][j]?"■":"□");
    }
    printf("\n");
  }



}

/************************************************************************
  メインプログラム
************************************************************************/
int main(int argc, char *argv[]){
	int t;
	int field[FieldSize][FieldSize];
 
	if(argc!=2){
		printf("実行方法 : ./a.out 初期状態のファイル\n");
	}
 
/* Linuxで実行する場合は //でコメントアウトしてあるところの
//を消すと表示のされ方が変わる */
 
//system("clear");
	init_field(field, argv[1]);
//display(field);
//sleep(1);
//system("clear");
	for(t=0;t<TimeMax;t++){
		update_field(field);
		display(field);
//sleep(1);
//system("clear");
	}
 
	return 0;
}
 
 
