commit a59602d1c70289131f26b880b91082eaef7dd7ec Author: hzhang Date: Sat Jan 18 08:30:10 2025 +0000 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/InverseOfLife.Test.csproj b/InverseOfLife.Test.csproj new file mode 100644 index 0000000..ef05db6 --- /dev/null +++ b/InverseOfLife.Test.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + enable + enable + + false + true + InverseOfLife.Test + + + + + + + + + + + + + + + diff --git a/InverseOfLife.Test.sln b/InverseOfLife.Test.sln new file mode 100644 index 0000000..593c2ba --- /dev/null +++ b/InverseOfLife.Test.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InverseOfLife.Test", "InverseOfLife.Test.csproj", "{DD3D4C28-4E98-4DE8-8D06-4F4F6CEF09EB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DD3D4C28-4E98-4DE8-8D06-4F4F6CEF09EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD3D4C28-4E98-4DE8-8D06-4F4F6CEF09EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD3D4C28-4E98-4DE8-8D06-4F4F6CEF09EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD3D4C28-4E98-4DE8-8D06-4F4F6CEF09EB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/tests/BoardTests.cs b/tests/BoardTests.cs new file mode 100644 index 0000000..6f1558a --- /dev/null +++ b/tests/BoardTests.cs @@ -0,0 +1,89 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; +[TestFixture] +public class BoardTests +{ + [Test] + public void BoardInitializationTest() + { + var board = new Board(5, 5); + + Assert.That(board.Width, Is.EqualTo(5)); + Assert.That(board.Height, Is.EqualTo(5)); + Assert.IsNotNull(board.Lives); + Assert.That(board.Lives.Count, Is.EqualTo(0)); + } + + [Test] + public void ToggleTest_AddAndRemoveCells() + { + var board = new Board(5, 5); + board.Toggle(2, 2); + Assert.That(board.Lives, Contains.Item((2, 2))); + board.Toggle(2, 2); + Assert.IsFalse(board.Lives.Contains((2, 2))); + } + + [Test] + public void EvaluateTest_WithSimpleRule() + { + var board = new Board(5, 5); + board.Toggle(2, 2); + board.Toggle(3, 2); + board.Toggle(4, 2); + Assert.IsTrue(board.Lives.Contains((2, 2))); + Assert.IsTrue(board.Lives.Contains((3, 2))); + Assert.IsTrue(board.Lives.Contains((4, 2))); + board.Evaluate(); + Assert.IsFalse(board.Lives.Contains((2, 2))); + Assert.IsTrue(board.Lives.Contains((3, 2))); + Assert.IsFalse(board.Lives.Contains((4, 2))); + Assert.IsTrue(board.Lives.Contains((3, 1))); + Assert.IsTrue(board.Lives.Contains((3, 3))); + } + + [Test] + public void ToStringTest_BasicGridRepresentation() + { + var board = new Board(5, 5); + + board.Toggle(1, 1); + board.Toggle(3, 2); + board.Toggle(4, 4); + + string expected = + " \n" + + " o \n" + + " o \n" + + " \n" + + " o\n"; + + Assert.That(board.ToString(), Is.EqualTo(expected)); + Console.Write(board.ToString()); + } + + [Test] + public void ToStringTest_WithEmptyBoard() + { + var board = new Board(3, 3); + + string expected = + " \n" + + " \n" + + " \n"; + + Assert.That(board.ToString(), Is.EqualTo(expected)); + } + + [Test] + public void PopulateTest_PeriodicBoundaryCondition() + { + var board = new Board(3, 3, true, true); + board.Toggle(0, 0); + var neighbourCount = new Dictionary<(int, int), int>(); + board.Populate(0, 0, neighbourCount); + Assert.That(neighbourCount[(1, 0)], Is.EqualTo(1)); + Assert.That(neighbourCount[(2, 2)], Is.EqualTo(1)); + } +} \ No newline at end of file diff --git a/tests/CellTracerTests.cs b/tests/CellTracerTests.cs new file mode 100644 index 0000000..4e4b5a0 --- /dev/null +++ b/tests/CellTracerTests.cs @@ -0,0 +1,105 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; + +[TestFixture] +public class CellTracerTests +{ + private Board board; + + [SetUp] + public void Setup() + { + board = new Board(5, 5, useTracer: true); + } + + [Test] + public void InitializeBoard_WithTracer_ShouldHaveNoCellsOrContributions() + { + var initialState = board.ToString(); + + Assert.IsNotNull(board.Tracer); + Assert.That(board.Tracer!.Contribution, Is.Empty); + } + + [Test] + public void Toggle_ShouldNotAffectTracer() + { + board.Toggle(1, 1); + board.Toggle(2, 2); + + Assert.That(board.Lives, Is.EquivalentTo(new[] { (1, 1), (2, 2) })); + Assert.That(board.Tracer!.Contribution, Is.Empty); // Tracer not affected by Toggle + } + + [Test] + public void Evaluate_WithTracer_ShouldTrackNewCellContributions() + { + board.Toggle(1, 2, initialConfig: true); + board.Toggle(2, 2, initialConfig: true); + board.Toggle(3, 2, initialConfig: true); + + board.Evaluate(); + + Assert.That(board.Lives, Is.EquivalentTo(new[] { (2, 1), (2, 2), (2, 3) })); + + var tracer = board.Tracer!; + Assert.That(tracer.Contribution.ContainsKey((2, 1)), Is.True); + Assert.That(tracer.Contribution.ContainsKey((2, 3)), Is.True); + + var contributions = tracer.Contribution[(2, 1)]; + Assert.That(contributions.Keys, Is.EquivalentTo(new[] { (1, 2), (2, 2), (3, 2) })); + Assert.That(contributions[(1, 2)], Is.EqualTo(1.0 / 3.0)); + Assert.That(contributions[(2, 2)], Is.EqualTo(1.0 / 3.0)); + Assert.That(contributions[(3, 2)], Is.EqualTo(1.0 / 3.0)); + } + + [Test] + public void Evaluate_WithTracer_ShouldRemoveDeadCellContributions() + { + board.Toggle(1, 2, initialConfig: true); + board.Toggle(2, 2, initialConfig: true); + board.Toggle(3, 2, initialConfig: true); + + board.Evaluate(); + + board.Evaluate(); + + Assert.That(board.Lives, Is.EquivalentTo(new[] { (2, 2), (1, 2), (3, 2) })); + + var tracer = board.Tracer!; + Assert.That(tracer.Contribution.ContainsKey((2, 2)), Is.True); + Assert.That(tracer.Contribution.ContainsKey((2, 1)), Is.False); + Assert.That(tracer.Contribution.ContainsKey((2, 3)), Is.False); + } + + [Test] + public void BatchProcess_ShouldApplyDeferredAddAndRemoveCorrectly() + { + board.Toggle(1, 2, initialConfig: true); + board.Toggle(2, 2, initialConfig: true); + board.Toggle(3, 2, initialConfig: true); + board.Evaluate(); + + Assert.That(board.Lives, Does.Contain((2, 1))); + Assert.That(board.Lives, Does.Not.Contain((1, 2))); + + Assert.That(board.Tracer!.Contribution.ContainsKey((1, 2)), Is.False); + Assert.That(board.Tracer!.Contribution.ContainsKey((2, 1)), Is.True); + } + + [Test] + public void Play_ShouldRunGenerationsAndUpdateTracer() + { + board.Toggle(1, 2, initialConfig: true); + board.Toggle(2, 2, initialConfig: true); + board.Toggle(3, 2, initialConfig: true); + + board.Play(3, delay: 0); + + Assert.That(board.Lives, Is.EquivalentTo(new[] { (2, 1), (2, 2), (2, 3) })); + + var tracer = board.Tracer!; + Assert.That(tracer.Contribution.ContainsKey((2, 2)), Is.True); + } +} \ No newline at end of file diff --git a/tests/EvoluteTests.cs b/tests/EvoluteTests.cs new file mode 100644 index 0000000..3f2d7ea --- /dev/null +++ b/tests/EvoluteTests.cs @@ -0,0 +1,46 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; +[TestFixture] +public class EvoluteTests +{ + [Test] + public void Mutate_ShouldModifyBitsBasedOnRate() + { + int resolution = 3; + byte[] riboseSequence = [0b10101010, 0b11110000, 0b00001111, 0b00110011]; + var gene = new Gene(resolution, riboseSequence); + + float mutationRate = 1.0f; + var mutatedGene = gene.Mutate(0, mutationRate); + + Assert.That(mutatedGene.RiboseSequence, Is.Not.EqualTo(riboseSequence)); + } + + [Test] + public void Mutate_WithZeroRate_ShouldNotChangeRiboseSequence() + { + int resolution = 3; + byte[] riboseSequence = [0b10101010, 0b11110000, 0b00001111, 0b00110011]; + var gene = new Gene(resolution, riboseSequence); + + float mutationRate = 0.0f; + var mutatedGene = gene.Mutate(0, mutationRate); + + Assert.That(mutatedGene.RiboseSequence, Is.EqualTo(riboseSequence)); + } + + [Test] + public void Mutate_WithSpecificRiboseIndex_ShouldOnlyAffectSpecifiedIndex() + { + int resolution = 3; + byte[] riboseSequence = [0b10101010, 0b11110000, 0b00001111, 0b00001111]; + var gene = new Gene(resolution, riboseSequence); + + float mutationRate = 0.5f; + int riboseIndex = 1; + var mutatedGene = gene.Mutate(riboseIndex, mutationRate); + + Assert.That(mutatedGene.RiboseSequence[0], Is.EqualTo(riboseSequence[0])); + } +} \ No newline at end of file diff --git a/tests/GeneEncodeDecodeTests.cs b/tests/GeneEncodeDecodeTests.cs new file mode 100644 index 0000000..25c603a --- /dev/null +++ b/tests/GeneEncodeDecodeTests.cs @@ -0,0 +1,124 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; +[TestFixture] +public class GeneEncodeDecodeTests +{ + [Test] + public void EncodeAndDecode_ShouldHandleResolution1Correctly() + { + int resolution = 1; + int width = 8; + int height = 8; + var board = new Board(width, height); + board.Toggle(0, 0); + board.Toggle(7, 7); + board.Toggle(3, 5); + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsTrue(restoredBoard.Lives.Contains((0, 0)), "Cell (0, 0) should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((7, 7)), "Cell (7, 7) should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((3, 5)), "Cell (3, 5) should be alive."); + Assert.That(restoredBoard.Lives, Is.EquivalentTo(board.Lives), "Restored board should match the original board."); + } + + [Test] + public void EncodeAndDecode_ShouldHandleResolution2Correctly() + { + int resolution = 2; + int width = 4; + int height = 4; + var board = new Board(width, height); + board.Toggle(0, 0); + board.Toggle(3, 3); + board.Toggle(2, 1); + board.Toggle(1, 2); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsTrue(restoredBoard.Lives.Contains((0, 0)), "Cell (0, 0) should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((3, 3)), "Cell (3, 3) should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((2, 1)), "Cell (2, 1) should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((1, 2)), "Cell (1, 2) should be alive."); + Assert.That(restoredBoard.Lives, Is.EquivalentTo(board.Lives), "Restored board should match the original board."); + } + + [Test] + public void EncodeAndDecode_ShouldHandleEmptyBoardResolution1() + { + int resolution = 1; + int width = 8; + int height = 8; + var board = new Board(width, height); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsEmpty(restoredBoard.Lives, "Restored board should be empty."); + } + + [Test] + public void EncodeAndDecode_ShouldHandleEmptyBoardResolution2() + { + int resolution = 2; + int width = 4; + int height = 4; + var board = new Board(width, height); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsEmpty(restoredBoard.Lives, "Restored board should be empty."); + } + + [Test] + public void EncodeAndDecode_ShouldHandleFullBoardResolution1() + { + int resolution = 1; + int width = 8; + int height = 8; + var board = new Board(width, height); + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + board.Toggle(x, y); + } + } + + var gene = new Gene(resolution, board); + foreach (byte b in gene.RiboseSequence) + { + Console.Write($"{b} "); + Console.WriteLine(); + } + var restoredBoard = gene.Restore(width, height); + Console.WriteLine("-"); + Console.WriteLine(restoredBoard.ToString()); + Console.WriteLine("="); + Assert.That(restoredBoard.Lives, Is.EquivalentTo(board.Lives), "Restored board should match the original full board."); + } + + [Test] + public void EncodeAndDecode_ShouldHandleFullBoardResolution2() + { + int resolution = 2; + int width = 4; + int height = 4; + var board = new Board(width, height); + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + board.Toggle(x, y); + } + } + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + Console.WriteLine(restoredBoard.ToString()); + Assert.That(restoredBoard.Lives, Is.EquivalentTo(board.Lives), "Restored board should match the original full board."); + } +} \ No newline at end of file diff --git a/tests/GeneIndexerTest.cs b/tests/GeneIndexerTest.cs new file mode 100644 index 0000000..825ecbe --- /dev/null +++ b/tests/GeneIndexerTest.cs @@ -0,0 +1,45 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; + +[TestFixture] +public class GeneIndexerTests +{ + [Test] + public void Indexer_GranularityPositive_ReadWriteBytes() + { + var riboseSequence = new byte[] { 0b10101010, 0b11110000, 0b00001111, 0b11001100 }; + var gene = new Gene(3, riboseSequence); + + byte[] expected = [0b00001111, 0b11001100]; + Assert.That(gene[1], Is.EqualTo(expected)); + + gene[1] = [0b01010101, 0b10101010]; + Assert.That(gene[1], Is.EqualTo(new byte[] { 0b01010101, 0b10101010 })); + } + + [Test] + public void Indexer_GranularityNegative_ReadWriteBits() + { + var riboseSequence = new byte[] { 0b10101010, 0b11110000 }; + var gene = new Gene(1, riboseSequence); + + byte[] expected = [0b00000001]; + Assert.That(gene[7], Is.EqualTo(expected)); + + gene[7] = [0b00000000]; + Assert.That(gene[7], Is.EqualTo(new byte[] { 0b00000000 })); + } + + [Test] + public void Indexer_GranularityExceed_ThrowsException() + { + var riboseSequence = new byte[] { 0b10101010, 0b11110000 }; + var gene = new Gene(3, riboseSequence); + + Assert.Throws(() => + { + gene[0] = [0b10101010, 0b11110000, 0b00001111]; + }); + } +} \ No newline at end of file diff --git a/tests/GeneTests.cs b/tests/GeneTests.cs new file mode 100644 index 0000000..cd49d2d --- /dev/null +++ b/tests/GeneTests.cs @@ -0,0 +1,140 @@ +using NUnit.Framework; +namespace InverseOfLife.Test; + +[TestFixture] +public class GeneTests +{ + [Test] + public void Gene_Constructor_FromBoard_CorrectEncoding() + { + int resolution = 4; + var board = new Board(8, 8); + board.Toggle(1, 1); + board.Toggle(5, 5); + + var gene = new Gene(resolution, board); + + int encodedBits = gene.RiboseSequence.Sum(b => CountSetBits(b)); + Assert.That(encodedBits, Is.EqualTo(2), "Encoded bits should match the number of live cells."); + } + + [Test] + public void Gene_Constructor_FromSequence_CorrectRestoration() + { + int resolution = 4; + var expectedBoard = new Board(8, 8); + expectedBoard.Toggle(1, 1); + expectedBoard.Toggle(5, 5); + var gene = new Gene(resolution, expectedBoard); + + var restoredBoard = gene.Restore(8,8); + + Assert.That(restoredBoard.Lives, Is.EquivalentTo(expectedBoard.Lives), "Restored board should match the original board."); + } + + [Test] + public void Gene_Constructor_EmptyBoard_RestoreEmptyBoard() + { + int resolution = 4; + var board = new Board(8, 8); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(8,8); + + Assert.IsEmpty(restoredBoard.Lives, "Restored board should be empty for an empty input board."); + } + + [Test] + public void Gene_Restore_LargerBoard() + { + int resolution = 4; + var board = new Board(16, 16); + board.Toggle(2, 2); + board.Toggle(10, 10); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(16,16); + + Assert.IsTrue(restoredBoard.Lives.Contains((2, 2)), "Cell (2, 2) should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((10, 10)), "Cell (10, 10) should be alive."); + Assert.That(restoredBoard.Lives, Is.EquivalentTo(board.Lives), "Restored board should match the original board."); + } + + [Test] + public void Gene_Restore_BoundaryCells() + { + + int resolution = 4; + var board = new Board(8, 8); + board.Toggle(0, 0); + board.Toggle(7, 7); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(8,8); + + Assert.IsTrue(restoredBoard.Lives.Contains((0, 0)), "Top-left corner cell should be alive."); + Assert.IsTrue(restoredBoard.Lives.Contains((7, 7)), "Bottom-right corner cell should be alive."); + Assert.That(restoredBoard.Lives, Is.EquivalentTo(board.Lives), "Restored board should match the original board."); + } + + [Test] + public void Gene_Restore_NonMultipleWidth() + { + int resolution = 4; + int width = 10; + int height = 8; + var board = new Board(width, height); + board.Toggle(9, 1); + board.Toggle(1, 7); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsTrue(restoredBoard.Lives.Contains((9, 1))); + Assert.IsTrue(restoredBoard.Lives.Contains((1, 7))); + } + + [Test] + public void Gene_Restore_NonMultipleHeight() + { + int resolution = 4; + int width = 8; + int height = 9; + var board = new Board(width, height); + board.Toggle(7, 8); + board.Toggle(0, 0); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsTrue(restoredBoard.Lives.Contains((7, 8))); + Assert.IsTrue(restoredBoard.Lives.Contains((0, 0))); + } + [Test] + public void Gene_Restore_NonMultipleWidthAndHeight() + { + int resolution = 4; + int width = 10; + int height = 9; + var board = new Board(width, height); + board.Toggle(9, 8); + board.Toggle(0, 0); + + var gene = new Gene(resolution, board); + var restoredBoard = gene.Restore(width, height); + + Assert.IsTrue(restoredBoard.Lives.Contains((9, 8))); + Assert.IsTrue(restoredBoard.Lives.Contains((0, 0))); + } + + private int CountSetBits(byte b) + { + int count = 0; + while (b > 0) + { + count += b & 1; + b >>= 1; + } + return count; + } +} diff --git a/tests/ScoreTests.cs b/tests/ScoreTests.cs new file mode 100644 index 0000000..d681b9f --- /dev/null +++ b/tests/ScoreTests.cs @@ -0,0 +1,176 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; + +[TestFixture] +public class ScoreTests +{ + [Test] + public void Score_AllCellsMatch_ReturnsOne() + { + var board1 = new Board(3, 3); + var board2 = new Board(3, 3); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(2, 2); + + board2.Toggle(0, 0); + board2.Toggle(1, 1); + board2.Toggle(2, 2); + + double score = Summarizer.Score(board1, board2); + Assert.That(score, Is.EqualTo(1.0)); + } + + [Test] + public void Score_NoMatchingCells_ReturnsZero() + { + var board1 = new Board(3, 3); + var board2 = new Board(3, 3); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(2, 2); + + board2.Toggle(0, 1); + board2.Toggle(1, 2); + board2.Toggle(2, 0); + + double score = Summarizer.Score(board1, board2); + Assert.That(score, Is.EqualTo(1d / 3d)); + } + + [Test] + public void Score_PartialMatch_ReturnsCorrectValue() + { + var board1 = new Board(3, 3); + var board2 = new Board(3, 3); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(2, 2); + + board2.Toggle(0, 0); + board2.Toggle(1, 2); + board2.Toggle(2, 1); + + double score = Summarizer.Score(board1, board2); + + double tp = 1; + double tn = 3 * 3 - 5; + double total = 9; + + Assert.That(score, Is.EqualTo((tp + tn) / total).Within(1e-8)); + } + + [Test] + public void ScoreBySubGrid_AllCellsMatch_ReturnsOneForAllSubGrids() + { + var board1 = new Board(4, 4); + var board2 = new Board(4, 4); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(2, 2); + board1.Toggle(3, 3); + + board2.Toggle(0, 0); + board2.Toggle(1, 1); + board2.Toggle(2, 2); + board2.Toggle(3, 3); + + var scores = Summarizer.ScoreBySubGrid(board1, board2, 2); + + Assert.That(scores[0], Is.EqualTo(1.0)); + Assert.That(scores[1], Is.EqualTo(1.0)); + Assert.That(scores[2], Is.EqualTo(1.0)); + Assert.That(scores[3], Is.EqualTo(1.0)); + } +/// +/// xx xx 02 03 +/// xx xx 12 13 +/// 20 21 xx xx +/// 30 31 xx xx +/// + [Test] + public void ScoreBySubGrid_NoMatchingCells_ReturnsZeroForAllSubGrids() + { + var board1 = new Board(4, 4); + var board2 = new Board(4, 4); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(2, 2); + board1.Toggle(3, 3); + + board2.Toggle(0, 1); + board2.Toggle(1, 0); + board2.Toggle(2, 3); + board2.Toggle(3, 2); + + var scores = Summarizer.ScoreBySubGrid(board1, board2, 2); + + Assert.That(scores[0], Is.EqualTo(0.0)); + Assert.That(scores[1], Is.EqualTo(1.0)); + Assert.That(scores[2], Is.EqualTo(1.0)); + Assert.That(scores[3], Is.EqualTo(0.0)); + } +/// +/// oo 01 02 03 +/// 10 xx xx 13 +/// xx 21 xx 23 +/// 30 31 32 oo +/// + [Test] + public void ScoreBySubGrid_PartialMatch_ReturnsCorrectScores() + { + var board1 = new Board(4, 4); + var board2 = new Board(4, 4); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(2, 2); + board1.Toggle(3, 3); + + board2.Toggle(0, 0); + board2.Toggle(1, 2); + board2.Toggle(3, 3); + board2.Toggle(2, 0); + + var scores = Summarizer.ScoreBySubGrid(board1, board2, 2); + + Assert.That(scores[0], Is.EqualTo(0.75d)); + Assert.That(scores[1], Is.EqualTo(0.75d)); + Assert.That(scores[2], Is.EqualTo(0.75d)); + Assert.That(scores[3], Is.EqualTo(0.75d)); + } +/// +/// oo 01 02 03 04 05 +/// 10 oo 12 13 14 15 +/// 20 21 22 23 24 25 +/// 30 31 32 33 34 35 +/// 40 41 42 43 oo 45 +/// 50 51 52 53 54 55 +/// + [Test] + public void ScoreBySubGrid_DifferentResolutions_CorrectSubGridCount() + { + var board1 = new Board(6, 6); + var board2 = new Board(6, 6); + + board1.Toggle(0, 0); + board1.Toggle(1, 1); + board1.Toggle(4, 4); + + board2.Toggle(0, 0); + board2.Toggle(1, 1); + board2.Toggle(4, 4); + + var scores2X2 = Summarizer.ScoreBySubGrid(board1, board2, 2); + var scores3X3 = Summarizer.ScoreBySubGrid(board1, board2, 3); + + Assert.That(scores2X2.Count, Is.EqualTo(9)); + Assert.That(scores3X3.Count, Is.EqualTo(4)); + } +} \ No newline at end of file diff --git a/tests/WeightTests.cs b/tests/WeightTests.cs new file mode 100644 index 0000000..066e02e --- /dev/null +++ b/tests/WeightTests.cs @@ -0,0 +1,36 @@ +using NUnit.Framework; + +namespace InverseOfLife.Test; +[TestFixture] +public class WeightTests +{ + [Test] + public void GetWeight_GeneralTest() + { + Board boardX = new Board(4, 4, useTracer: true); + Board boardY = new Board(4, 4); + boardX.Toggle(0, 1, true); + boardX.Toggle(1, 1, true); + boardX.Toggle(2, 1, true); + Console.WriteLine(boardX.ToString()); + boardX.Evaluate(); + + boardY.Toggle(1, 2); + boardY.Toggle(1, 3); + + var t = Summarizer.GetWeight(boardX, boardY, 2); + Assert.That(t.Length, Is.EqualTo(4)); +// Assert.That(t[0], Is.EqualTo(0)); + + Console.WriteLine(t[0]); + Console.WriteLine(t[1]); + Console.WriteLine(t[2]); + Console.WriteLine(t[3]); + + Console.WriteLine(boardX.ToString()); + Assert.That(t[1], Is.GreaterThan(0)); + + + + } +} \ No newline at end of file