public void FiveStepsAwayFromMaxWinning_IterativeSearch_ReuseCache_MaxWin(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = Connect4TestUtils.GetMaxFiveMovesAwayFromWinningState(); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode, 1, CacheMode.ReuseCache); var evaluation = new IterativeSearchWrapper(engine).IterativeSearch(startState, 1, 8, CancellationToken.None); Assert.AreEqual(BoardEvaluator.MaxEvaluation, evaluation.Evaluation); }
public void BenchmarkConnect4() { var searchDepth = 11; var board = Connect4TestUtils.GetEmptyBoard(); Benchmark(board, searchDepth, ParallelismMode.NonParallelism); Benchmark(board, searchDepth, ParallelismMode.FirstLevelOnly); Benchmark(board, searchDepth, ParallelismMode.ParallelismByLevel, levelOfParallelism: 2); Benchmark(board, searchDepth, ParallelismMode.TotalParallelism, 4); }
public void FiveStepsAwayFromMaxWinning_MaxTurn_MaxWin(int degreeOfParallelism, ParallelismMode parallelismMode, CacheMode cacheMode) { var startState = Connect4TestUtils.GetMaxFiveMovesAwayFromWinningState(); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode, 1, CacheMode.ReuseCache); var evaluation = engine.Search(startState, 5); Assert.AreEqual(BoardEvaluator.MaxEvaluation, evaluation.Evaluation); Assert.IsTrue(BoardEvaluator.IsWin(((Connect4State)evaluation.StateSequence.Last()).Board, Player.Max), "Should have found a wining state"); Assert.IsTrue(evaluation.AllChildrenAreDeadEnds, "All children should be dead ends"); }
public void FiveStepsAwayFromMaxWinning_ReuseCache_DontDieEarly_MaxWin(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = Connect4TestUtils.GetMaxFiveMovesAwayFromWinningState(); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode, 1, CacheMode.ReuseCache); engine.DieEarly = false; engine.Search(startState, 5); Assert.IsTrue(((StateCacheManager)engine.CacheManager).Count > 0, "The cache doesn't contain any states"); var evaluation = engine.Search(startState, 5); Assert.AreEqual(BoardEvaluator.MaxEvaluation, evaluation.Evaluation); }
private void Benchmark(Player[,] startBoard, int searchDepth, ParallelismMode parallelismMode = ParallelismMode.FirstLevelOnly, int degreeOfParallelism = 1, int levelOfParallelism = 1) { Console.WriteLine(GetTestMessage(parallelismMode, degreeOfParallelism, levelOfParallelism)); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode, levelOfParallelism); var startState = new Connect4State(startBoard, Player.Max); var results = engine.Search(startState, searchDepth); Console.WriteLine("Time: " + results.SearchTime); Console.WriteLine("Leaves: " + results.Leaves); Console.WriteLine("InternalNodes: " + results.InternalNodes); }
public void NewGame_CheckCancellationToken(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = new Connect4State(Connect4TestUtils.GetEmptyBoard(), Player.Max); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode); var cancellationSource = new CancellationTokenSource(); var searchTask = engine.SearchAsync(startState, 20, cancellationSource.Token); Thread.Sleep(500); cancellationSource.Cancel(); Thread.Sleep(500); Assert.IsTrue(searchTask.IsCompleted, "Search should have complated by now"); var t = searchTask.Result; // Check that we can get a result even if the search was terminated }
public void FiveStepsAwayFromMaxWinning_FillCache_MaxWin(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = Connect4TestUtils.GetMaxFiveMovesAwayFromWinningState(); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode, 1, CacheMode.ReuseCache); engine.DieEarly = true; engine.FillCache(startState, CancellationToken.None); Assert.IsTrue(((StateCacheManager)engine.CacheManager).Count > 0, "The cache doesn't contain any states"); Assert.IsNotNull(engine.CacheManager.GetStateEvaluation(startState, 0, null), "The cache doesn't contain the start state"); var evaluation = engine.Search(startState, 5); Assert.AreEqual(BoardEvaluator.MaxEvaluation, evaluation.Evaluation); }
public void ThreeStepsAwayFromMaxWinning_MaxTurn_MaxWin(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = new Connect4State(new[, ] { { Player.Empty, Player.Empty, Player.Empty, Player.Max, Player.Max, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, }, Player.Max); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode); var evaluation = engine.Search(startState, 3); Assert.IsTrue(BoardEvaluator.IsWin(((Connect4State)evaluation.StateSequence.Last()).Board, Player.Max), "Should have found a wining state"); }
public void TwoStepsAwayFromMaxWinning__MinsTurn_DontLetMinMax(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = new Connect4State(new[, ] { { Player.Empty, Player.Max, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Max, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Max, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, }, Player.Min); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode); var newState = (Connect4State)engine.Search(startState, 2).NextMove; Assert.AreEqual(Player.Min, newState.Board[3, 1], "Min didn't block Max's win"); }
public void OneStepAwayFromMaxWinning_MaxTurn_MaxWin(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = new Connect4State(new[, ] { { Player.Empty, Player.Max, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Max, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Max, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, { Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty, Player.Empty }, }, Player.Max); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode); var evaluation = engine.Search(startState, 2); Assert.IsTrue(BoardEvaluator.IsWin(((Connect4State)evaluation.NextMove).Board, Player.Max), "Should have found a wining state"); Assert.AreEqual(1, evaluation.StateSequence.Count, "StateSequence should only have one state in it"); }
public void NewGame_NoOneCanWin(int degreeOfParallelism, ParallelismMode parallelismMode) { var startState = new Connect4State(Connect4TestUtils.GetEmptyBoard(), Player.Max); var engine = Connect4TestUtils.GetSearchEngine(degreeOfParallelism, parallelismMode); var evaluation = engine.Search(startState, 7); Assert.IsFalse(BoardEvaluator.IsWin(((Connect4State)evaluation.StateSequence.Last()).Board, Player.Max)); Assert.IsFalse(evaluation.FullTreeSearchedOrPruned); Assert.IsFalse(evaluation.AllChildrenAreDeadEnds); if (degreeOfParallelism == 1) { //Check that the our optimizations are working Assert.IsTrue(evaluation.Leaves < 26000, "Too many leaves in search. Leaves = " + evaluation.Leaves); Assert.IsTrue(evaluation.InternalNodes < 10000, "Too many intarnal nodes in search. Nodes = " + evaluation.InternalNodes); } // Too few leaves or internal nodes means that something went wrong Assert.IsTrue(evaluation.Leaves > 1000, "Too few leaves in search. Leaves = " + evaluation.Leaves); Assert.IsTrue(evaluation.InternalNodes > 1000, "Too few intarnal nodes in search. Nodes = " + evaluation.InternalNodes); }
public void BenchmarkConnect4_HalfFullBoard() => Benchmark(Connect4TestUtils.GetHalfFullBoard(), 20);