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