#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++){
			i_tmp=I+i;
			j_tmp=J+j;

			/* 自分自身は数えない */
			if(i==0 && j==0){
				continue;
			}
			/* 範囲外も数えない */
			if(i_tmp<0 || i_tmp>=FieldSize){
				continue;
			}
			if(j_tmp<0 || j_tmp>=FieldSize){
				continue;
			}

			sum+=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);
			if(around==3){
				/* 周囲に3つ1があれば次の状態は1 */
				new_field[i][j]=1;
			} else if(around==2 && field[i][j]==1){
				/* 周囲に2つ1があり、現在の状態が1であれば 次の状態は1 */
				new_field[i][j]=1;
			} else {
				new_field[i][j]=0;
			}
		}
	}
 
	/* 次の状態の情報(new_field)を fieldにコピー */
	for(i=0;i<FieldSize;i++){
		for(j=0;j<FieldSize;j++){
			field[i][j]=new_field[i][j];
		}
	}
}
 
/************************************************************************
  状態(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");
	}
	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;
}
 
 
