public void TestDFirstSimulation() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); b.Play((0, 2, 0, 1)); // This board position has only one available play. GameTreeNode t = new GameTreeNode((0, 2, 0, 1)); float score = t.Simulate(b); GameTreeNode child = null; try { child = t.GetChild((1, 0, 0, 2)); // The only possible child. } catch (Exception) { // Ignore any exception. } Assert.Multiple(() => { Assert.That(score, Is.EqualTo(0)); // The only play wins for the opponent. Assert.That(child, Is.Null); // Check that no child was retrieved. }); }
public void TestCSimulateOWin() { UltimateBoard b = Games.GetBoard(Games.OWins, Games.OWins.Length); GameTreeNode t = new GameTreeNode(Games.OWins[Games.OWins.Length - 1]); Assert.That(t.Simulate(b), Is.EqualTo(1)); }
public void TestCSimulateDraw() { UltimateBoard b = Games.GetBoard(Games.Draw, Games.Draw.Length); GameTreeNode t = new GameTreeNode(Games.Draw[Games.Draw.Length - 1]); Assert.That(t.Simulate(b), Is.EqualTo(0.5f)); }
public void TestGGetChildForSimulationFirstTimeThrough() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); b.Play((0, 2, 2, 0)); b.Play((0, 2, 0, 1)); GameTreeNode t = new GameTreeNode((0, 2, 0, 1)); t.Simulate(new UltimateBoard(b)); // A random simulation. float[] scores = new float[2]; scores[0] = t.Simulate(new UltimateBoard(b)); // The above adds the two children, (0, 2, 1, 0) and (1, 0, 0, 2), and does a random simulation on one of them. // The child chosen might be either, depending on the implementation. In each case, there is only one possible // continuation. If (0, 2, 1, 0) is chosen, the value returned will be 1; otherwise, the value will be 0.5. scores[1] = t.Simulate(new UltimateBoard(b)); // The above does a random simulation on the other child; hence, the value returned should be either 1 or 0.5, // whichever value wasn't returned by the previous simulation. float[] correct = { 1, 0.5f }; }
public void TestHGetChildForSimulationUsingFormula() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); b.Play((0, 2, 2, 0)); b.Play((0, 2, 0, 1)); GameTreeNode t = new GameTreeNode((0, 2, 0, 1)); t.Simulate(new UltimateBoard(b)); // A random simulation. t.Simulate(new UltimateBoard(b)); // The above adds the two children, (0, 2, 1, 0) and (1, 0, 0, 2), and does a random simulation on one of them. t.Simulate(new UltimateBoard(b)); // The above does a random simulation on the other child. // At this point, the results of any further simulations are determined entirely by whichever child maximizes // the formula. The results should therefore be the same for any correct implementation. float[] scores = new float[10]; for (int i = 0; i < scores.Length; i++) { scores[i] = t.Simulate(new UltimateBoard(b)); } float[] correct = { 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f }; Assert.That(scores, Is.EqualTo(correct)); // The same values in the same order }
public void TestFSimulateAllChildrenOnce() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); // This board position has four available plays. GameTreeNode t = new GameTreeNode((1, 0, 1, 2)); for (int i = 0; i < 5; i++) { // The second iteration adds the four children and does a simulation on one // of them. The next three should each do a simulation on a different child // without adding any grandchildren. t.Simulate(new UltimateBoard(b)); } List <(int, int, int, int)> avail = b.GetAvailablePlays(); StringBuilder results = new StringBuilder(); foreach ((int, int, int, int)play in avail) { GameTreeNode grandchild = null; try { grandchild = t.GetChild(play).GetChild((1, 0, 0, 2)); // (1, 0, 0, 2) is an available response to each available play. results.Append(grandchild.Play.ToString()); } catch // The above will throw an exception if the grandchild hasn't been added. { results.Append("OK;"); } } Assert.That(results.ToString(), Is.EqualTo("OK;OK;OK;OK;")); // t should not contain any of the grandchildren. }
public void TestBWinNextTurn() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); b.Play((0, 2, 1, 0)); // Now the only available play wins the game. Assert.That(RandomSimulator.Simulate(b), Is.EqualTo(0)); }
public void Test_Field_IsActiveMicroboard() { var board = new UltimateBoard(); var field = new Field(board); field.ParseFromString(".,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,."); field.ParseMacroboardFromString("-1,-1,-1,-1,-1,-1,-1,-1,-1"); var moves = board.AvailableMoves; Assert.IsTrue(moves.Count == UltimateBoard.Rows * UltimateBoard.Cols); }
public void Test_Board_GameStatus_MoreMovesAvailable() { var boardString = "XOX|XXX|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var macroboard = "TXO|XOA|XOX"; var board = new UltimateBoard(); board.ParseFromString(boardString); board.ParseMacroboardFromString(macroboard); // More moves available in center-right of microboard Assert.IsTrue(board.GetGameStatus() == UltimateBoard.GameStatus.MovesAvailable); }
public void Test_Board_GameStatus_OWon() { var boardString = "XXX|OOO|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var macroboard = "TOO|XOT|XOX"; var board = new UltimateBoard(); board.ParseFromString(boardString); board.ParseMacroboardFromString(macroboard); // Tie Assert.IsTrue(board.GetGameStatus() == UltimateBoard.GameStatus.OWon); }
public void Test_Board_MakeMove_OccupiedPosition() { var boardString = "XOX|XXX|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var board = new UltimateBoard(); board.ParseFromString(boardString); // This position is occupied var move = new Move(1, 0); board.MakeMove(move, UltimateBoard.PlayerX); }
public void Test_Board_MakeMove_TieMove() { var boardString = "X.X|XXX|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var board = new UltimateBoard(); board.ParseFromString(boardString); // Tie the upper-left corner of microboard var move = new Move(1, 0); board.MakeMove(move, UltimateBoard.PlayerO); Assert.IsTrue(board.Macroboard[0, 0] == UltimateBoard.Tied); }
public void TestBAddChildren() { UltimateBoard b = Games.GetBoard(Games.XWins, 43); GameTreeNode t = new GameTreeNode(Games.XWins[42]); t.AddChildren(b); List <(int, int, int, int)> avail = b.GetAvailablePlays(); List <(int, int, int, int)> children = new List <(int, int, int, int)>(); foreach ((int, int, int, int)play in avail) { children.Add(t.GetChild(play).Play); // Get the specified child and retrieve its play } Assert.That(children, Is.EquivalentTo(avail)); }
public void TestJGetBestChildLargerTree() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); GameTreeNode t = new GameTreeNode((1, 0, 1, 2)); for (int i = 0; i < 100; i++) { t.Simulate(new UltimateBoard(b)); } Assert.That(t.GetBestChild().Play, Is.EqualTo((1, 0, 0, 2))); }
public void Test_Board_MakeMove_PlayerXWins() { // Make winning move in upper-left microboard var boardString = "X.X|XXX|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var board = new UltimateBoard(); board.ParseFromString(boardString); // Win the microboard var move = new Move(1, 0); board.MakeMove(move, UltimateBoard.PlayerX); // X won upper-left corner of macroboard Assert.IsTrue(board.Macroboard[0, 0] == UltimateBoard.PlayerX); }
public void TestELargerTree() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); float sum = 0; for (int i = 0; i < 1000; i++) { sum += RandomSimulator.Simulate(new UltimateBoard(b)); } Assert.That(sum / 1000, Is.GreaterThan(0.76).And.LessThan(0.86)); }
public void TestBPlaysAvailableAfterFirst() { UltimateBoard b = new UltimateBoard(); b.Play((0, 0, 0, 2)); List <(int, int, int, int)> avail = new List <(int, int, int, int)>(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { avail.Add((0, 2, i, j)); // Add all squares on small board (0, 2); } } Assert.That(b.GetAvailablePlays(), Is.EquivalentTo(avail)); }
public void TestESecondSimulation() { UltimateBoard b = Games.GetBoard(Games.Draw, 53); b.Play((1, 0, 1, 0)); b.Play((1, 0, 0, 0)); b.Play((0, 1, 2, 0)); b.Play((1, 0, 1, 2)); b.Play((0, 2, 0, 1)); // This board position has only one available play. GameTreeNode t = new GameTreeNode((0, 2, 0, 1)); t.Simulate(new UltimateBoard(b)); // The first simulation should not add a child (see above). float score = t.Simulate(new UltimateBoard(b)); // The second simulation should add the child. Assert.Multiple(() => { Assert.That(score, Is.EqualTo(0)); // The only play wins for the opponent. Assert.That(t.GetChild((1, 0, 0, 2)).Play, Is.EqualTo((1, 0, 0, 2))); // Check that the child was retrieved. }); }
public void TestAAllPlaysInitiallyAvailable() { List <(int, int, int, int)> allPlays = new List <(int, int, int, int)>(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { for (int m = 0; m < 3; m++) { for (int n = 0; n < 3; n++) { allPlays.Add((i, j, m, n)); // Add each square on the board. } } } } UltimateBoard b = new UltimateBoard(); Assert.That(b.GetAvailablePlays(), Is.EquivalentTo(allPlays)); }
public void Test_Board_IsWinnerMicroBoard() { var boardString = "XOX|XXX|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var board = new UltimateBoard(); board.ParseFromString(boardString); var results = "TXO|XO?|XOX"; int count = 0; for (int y = 0; y < UltimateBoard.Rows / 3; y++) { for (int x = 0; x < UltimateBoard.Cols / 3; x++) { string help = "[" + x + "," + y + "] winner should be is " + results[count]; if (results[count] == 'T' || results[count] == '?') { // No winner if tied or undecided Assert.IsFalse(board.IsWinnerMicroBoard(board.Board, x, y, UltimateBoard.PlayerX), help); Assert.IsFalse(board.IsWinnerMicroBoard(board.Board, x, y, UltimateBoard.PlayerO), help); } else if (results[count] == 'X') { Assert.IsTrue(board.IsWinnerMicroBoard(board.Board, x, y, UltimateBoard.PlayerX), help); Assert.IsFalse(board.IsWinnerMicroBoard(board.Board, x, y, UltimateBoard.PlayerO), help); } else if (results[count] == 'O') { Assert.IsFalse(board.IsWinnerMicroBoard(board.Board, x, y, UltimateBoard.PlayerX), help); Assert.IsTrue(board.IsWinnerMicroBoard(board.Board, x, y, UltimateBoard.PlayerO), help); } count++; } // Skip vertical bar count++; } }
public void Test_Board_IsActiveMicroboard() { var board = new UltimateBoard(); var macroboard = "A..|...|..."; board.ParseMacroboardFromString(macroboard); for (int y = 0; y < Field.Rows; y++) { for (int x = 0; x < Field.Cols; x++) { if (x >= 0 && x <= 2 && y >= 0 && y <= 2) { Assert.IsTrue(board.IsActiveMicroboard(x, y)); } else { Assert.IsFalse(board.IsActiveMicroboard(x, y), "Should be false for microboard [" + x + "," + y + "]"); } } } }
public void Text_Board_IsTieMicroBoard() { var boardString = "XOX|XXX|.XX|OXX|O..|OOO|OXO|..O|.OO|OXX|OOO|XOO|XXX|OX.|.XX|.O.|O..|OO.|O..|OOO|.OX|XXX|...|...|..O|XXO|XXX"; var board = new UltimateBoard(); board.ParseFromString(boardString); for (int y = 0; y < Field.Rows / 3; y++) { for (int x = 0; x < Field.Cols / 3; x++) { if (x == 0 && y == 0) { Assert.IsTrue(board.IsTieMicroBoard(board.Board, x, y), "[" + x + "," + y + "]"); } else { Assert.IsFalse(board.IsTieMicroBoard(board.Board, x, y), "[" + x + "," + y + "]"); } } } }
public void TestBPlaysAvailableAfterFirstSameBoard() { UltimateBoard b = new UltimateBoard(); b.Play((1, 2, 1, 2)); (int, int, int, int)[] avail =
public void TestANewGameNotWon() { UltimateBoard b = new UltimateBoard(); Assert.That(b.IsWon, Is.False); }
public void TestANewGameNotOver() { UltimateBoard b = new UltimateBoard(); Assert.That(b.IsOver, Is.False); }
public void TestADrawnGame() { UltimateBoard b = Games.GetBoard(Games.Draw, Games.Draw.Length); // Play the game to the end. Assert.That(RandomSimulator.Simulate(b), Is.EqualTo(0.5f)); }
public BotState() { UltimateBoard = new UltimateBoard(); Field = new Field(UltimateBoard); Players = new Dictionary <string, Player>(); }
public void TestAWonBySecond() { UltimateBoard b = Games.GetBoard(Games.OWins, Games.OWins.Length); // Play the game until O wins. Assert.That(RandomSimulator.Simulate(b), Is.EqualTo(1)); }