//http://ja.doukaku.org/126/ 投稿用

//Wikipediaライフゲーム
//http://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0

using System;
using System.Collections.Generic;
class LifeGame {
	const int SIZE = 10;//変更したらCellクラスのSIZEも要変更
	static void Main(string[] args) {
		string start =
@"
□■□□□□■□□□
■□□□□■□□□□
■■■□□■■■□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□
□□□□□□□□□□";//SIZE * SIZEの文字列
		start = start.TrimStart(new char[] { '\n', '\r' });//最初の改行を取り除く
		char[][] field = new char[SIZE][];//ライフゲームテーブル
		List<Cell> cells = new List<Cell>();//セル

		//startをfieldにセットする
		for(int y = 0; y < SIZE; y++) {//行でループ
			field[y] = start.Split(new char[] { '\n' })[y].ToCharArray();//改行で分割して文字配列にしてセット
		}

		//fieldからCellを生成
		for(int y = 0; y < SIZE; y++) {//field縦ループ
			for(int x = 0; x < SIZE; x++) {//field横ループ
				cells.Add(new Cell(field, x, y, field[y][x] == '■'));//Cellに座標をセットしてcellsに追加
			}
		}

		//メインループ
		while(true) {
			//出力
			Console.Clear();
			foreach(char[] str in field) {
				Console.WriteLine(str);
			}

			System.Threading.Thread.Sleep(300);//ウェイト			

			//次回の生死を判定、セット
			foreach(Cell cell in cells) {
				cell.SetNextLife();
			}

			//判定した生死をfieldに反映
			foreach(Cell cell in cells) {
				cell.SetField();
			}
		}
	}
}

//各セルのデータ
class Cell {
	const int SIZE = 10;//変更したらLifeGameクラスのSIZEも要変更
	char[][] Field;

	//位置
	int X;
	int Y;

	bool Life;//状態
	bool NextLife;//次回の状態(一時保存用)

	public Cell(char[][] field, int x, int y, bool life) {
		Field = field;
		X = x;
		Y = y;
		Life = life;
	}

	//次回の生死を判定
	public void SetNextLife() {
		switch(GetCount()) {
		case 3://誕生、維持
			NextLife = true;
			break;
		case 2://維持
			NextLife = Life;
			break;
		default://死亡
			NextLife = false;
			break;
		}
	}

	//判定した生死をfieldに反映
	public void SetField() {
		Field[Y][X] = NextLife ? '■' : '□';
		Life = NextLife;
	}

	//セル周囲の生きているセルをカウント
	private int GetCount() {
		int count = 0;
		for(int y_ = -1; y_ <= 1; y_++) {
			for(int x_ = -1; x_ <= 1; x_++) {
				if(!(x_ == 0 && y_ == 0)) {
					int locationX = GetRoopLocation(X, x_);
					int locationY = GetRoopLocation(Y, y_);
					if(Field[locationY][locationX] == '■') count++;
				}
			}
		}
		return count;
	}

	//fieldの端と端を繋ぐ
	private int GetRoopLocation(int location, int direction) {
		switch(location + direction) {
		case -1:
			return SIZE - 1;
		case SIZE:
			return 0;
		default:
			return location + direction;
		}
	}
}