C#の素振り

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NUnit.Framework.Constraints;

[TestFixture]
public class LifeGameTest
{
	[Test]
	public void Any_live_cell_with_fewer_than_two_live_neighbours_dies__as_if_caused_by_underpopulation()
	{
		var target = new Space("xxx",
		          			   "xoo",
		                       "xxx");
		Assert.That(target.Next().Cell(1, 1), Is.EqualTo('x'));
		Assert.That(target.Next(), new IsEqualsSpace("xxx",
		                                             "xxx",
		                                             "xxx"));
	}

	[Test]
	public void Any_live_cell_with_more_than_three_live_neighbours_dies__as_if_by_overcrowding()
	{
		var target = new Space("ooo",
		                       "oox",
		                       "xxx");
		Assert.That(target.Next().Cell(1, 1), Is.EqualTo('x'));
		Assert.That(target.Next(), new IsEqualsSpace("oxo",
		                                             "oxo",
		                                             "xxx"));
	}

	[Test]
	public void Any_live_cell_with_two_or_three_live_neighbours_lives_on_to_the_next_generation()
	{
		var targetTwoAlive = new Space("oox",
		                          "xox",
		                          "xxx");
		Assert.That(targetTwoAlive.Next().Cell(1, 1), Is.EqualTo('o'));

		var targetThreeAlive = new Space("ooo",
		                            "xox",
		                            "xxx");
		Assert.That(targetThreeAlive.Next().Cell(1, 1), Is.EqualTo('o'));

	}

	[Test]
	public void Any_dead_cell_with_exactly_three_live_neighbours_becomes_a_live_cell()
	{
		var target = new Space("oox",
		                       "oxx",
		                       "xxx");
		Assert.That(target.Next().Cell(1, 1), Is.EqualTo('o'));
	}
	

	public Space expectedSpace (params string[] cells)
	{
		return new  Space(cells);
	}

	[Test]
	public void sample()
	{
		var target = new Space("xoox",
		                       "ooox",
		                       "xoxx");
		Assert.That(target.Next(), new IsEqualsSpace("oxox",
		                                             "oxxx",
		                                             "ooox"));
	}
	

	[Test]
	public void CountAlive()
	{
		var target = new Space("oxx",
		                       "xoo",
		                       "xox");
		Assert.That(target.CountAlive(0, 0), Is.EqualTo(1));
		Assert.That(target.CountAlive(0, 1), Is.EqualTo(3));
		Assert.That(target.CountAlive(0, 2), Is.EqualTo(2));
		Assert.That(target.CountAlive(1, 1), Is.EqualTo(3));
		Assert.That(target.CountAlive(2, 0), Is.EqualTo(2));
		Assert.That(target.CountAlive(2, 2), Is.EqualTo(3));
	}
}

public class IsEqualsSpace : Constraint
{
	string expectedStr;
	string actualStr;
	
	public IsEqualsSpace (params string[] rows)
	{
		this.expectedStr = new Space(rows).ToCellsString();
	}
	
	public override bool Matches (object actual)
	{
		this.actual = actual;
		if (!(actual is Space)) {
			this.actualStr = "NotSpace";
			return false;
		}
		this.actualStr = ((Space)actual).ToCellsString();
		return this.actualStr == expectedStr;
	}
	
	public override void WriteDescriptionTo(MessageWriter writer)
	{
		writer.WriteExpectedValue(expectedStr);
	}
	
	public override void WriteActualValueTo (MessageWriter writer)
	{
		writer.WriteValue(actualStr);
	}
}



public class Space {
	public class _Cell {
		public readonly int row;
		public readonly int col;
		public readonly char status;

		public _Cell(int row, int col, char status) {
			this.row = row;
			this.col = col;
			this.status = status;
		}

		public _Cell Clone ()
		{
			return new _Cell(row, col, status);
		}
		
		public _Cell Clone (char status)
		{
			return new _Cell(this.row, this.col, status);
		}

		public _Cell Next (Space currentSpace)
		{
			if(status == 'o' && currentSpace.CountAlive(row, col) <= 1) {
				return Clone('x');
			}
			if(status == 'o' && currentSpace.CountAlive(row, col) >= 4) {
				return Clone('x');
			}
			if(status == 'x' && currentSpace.CountAlive(row, col) == 3) {
				return Clone('o');
			}
			return Clone();
		}
	}

	private List<_Cell> cells = new List<_Cell>();

	public Space(params string[] rows)
	{
		for (int row = 0; row < rows.Length; row++) 
		{
			char[] rowChars = rows[row].ToCharArray();
			for (int col = 0; col < rows[row].Length; col++)
			{
				cells.Add(new _Cell(row, col, rowChars[col]));
			}
		}
	}

	public Space(List<_Cell> cells)
	{
		this.cells = cells;
	}

	public Space Next()
	{
		return new Space(cells.Select(c => c.Next(this)).ToList());
	}
	
	public char Cell(int row, int col) 
	{
		return cells.First(cell => cell.row == row && cell.col == col).status;
	}

	public int CountAlive (int row, int col)
	{
		return cells.Where(c => (row-1 <= c.row && c.row <= row + 1) && 
		                        (col-1 <= c.col && c.col <= col + 1) &&
		                        !(row == c.row && col == c.col) &&
		                        (c.status == 'o')).Count();
	}

	public string ToCellsString ()
	{
		StringBuilder results = new StringBuilder ();
		int current = 0;
		foreach (var cell in cells) {
			if (current != cell.row) {
				results.Append ("\n");
				current ++;
			}
			results.Append (cell.status);
		}
		return results.ToString();
	}
}


public class MainClass {
	public static void Main ()
	{
	}
}

C#には、LINQ というやつがあるらしい。SQLライクに書くか、ブロック渡しライクに書くかの選択が出来る模様(ちと迷うな。)。上記は、SQLライクに書いていない。
LINQ おもったより提供しているものが多い。
http://msdn.microsoft.com/ja-jp/library/vstudio/bb384065.aspx
http://ufcpp.net/study/csharp/sp3_stdqueryo.html