public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta) { ZobristHash lZobristHash = Board.ZobristHash.Clone(); lZobristHash.Mark(playerToMove); int lTryMove = CoordinateSystem.PASS; if (depth > 1) { TranspositionTablePlus.Node lNode = TranspositionTable.Retrieve(lZobristHash); if ((lNode.Flag != TranspositionTablePlus.NodeType.Unknown) && (lNode.Height > 0)) { if ((maxPly - depth) <= lNode.Height) { TranspositionTableHits++; switch (lNode.Flag) { case TranspositionTablePlus.NodeType.Exact: { SearchComplete = false; return(lNode.Value); } case TranspositionTablePlus.NodeType.LowerBound: { alpha = (alpha > lNode.Value) ? alpha : lNode.Value; break; } case TranspositionTablePlus.NodeType.UpperBound: { beta = (beta < lNode.Value) ? beta : lNode.Value; break; } } if (alpha >= beta) { return(lNode.Value); } } lTryMove = lNode.Move; } } if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { if (depth == maxPly) { SearchComplete = false; } NodesEvaluated++; int lEval = SearchInterface.Evaluate(playerToMove); if (lEval <= alpha) { TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.LowerBound, CoordinateSystem.PASS, lZobristHash); } else if (lEval >= beta) { TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.UpperBound, CoordinateSystem.PASS, lZobristHash); } else { TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.Exact, CoordinateSystem.PASS, lZobristHash); } return(lEval); } MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); SearchInterface.PrioritizeMoves(lMoves, playerToMove); if (lTryMove != CoordinateSystem.PASS) { if (lMoves.Contains(lTryMove)) { lMoves.SetValue(lTryMove, Int32.MaxValue); } } if ((SearchOptions.UsePatterns) && (lMoves.Count != 0)) { PatternMap lPatternMap = SearchOptions.PatternDetector.FindPatterns(Board, playerToMove, lMoves.AllMoves); lPatternMap.UpdateMoveList(lMoves); } if (lMoves.Count == 0) { lMoves.Add(CoordinateSystem.PASS); } if ((lMoves.Count == 1) && (lMoves[0] == CoordinateSystem.PASS) && (Board.LastMove == CoordinateSystem.PASS)) { int lEval = SearchInterface.Evaluate(playerToMove); //TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.Exact, CoordinateSystem.PASS, lZobristHash); return(lEval); } if (Nag) { lock (this) { NagNode lNagNode = NagCoordinator.GetResult(depth); if (lNagNode != null) { if (!lNagNode.IsNarrowed()) { Console.Error.WriteLine("*** Pruning *** " + lNagNode.StartDepth.ToString() + "/" + lNagNode.Depth.ToString()); if (lNagNode.Depth == 1) { BestMove = lNagNode.BestMove; NagCoordinator.Abort(depth); return(lNagNode.Result); } SolvedDepth = lNagNode.StartDepth; SolvedValue = lNagNode.Result; NagCoordinator.Abort(depth); return(alpha); } } else { Nag = false; } } } SearchInterface.SortMoveList(lMoves); if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } NagCoordinator.CreateNagPoints(Board, alpha, beta, playerToMove, depth, maxPly, lMoves.Count, 2); int lSuperKoCount = 0; TranspositionTablePlus.NodeType lFlag = TranspositionTablePlus.NodeType.UpperBound; int lBestMove = lMoves[0]; foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAB_ID_TT.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1, -beta, -alpha); Board.Undo(); if (SolvedDepth != -1) { if (SolvedDepth != depth) { return(alpha); } alpha = SolvedValue; BestMove = lMove; SolvedDepth = -1; break; } if (lScore > alpha) { if (depth == 0) { BestMove = lMove; } if (lScore >= beta) { TranspositionTable.Record(maxPly - depth, alpha, TranspositionTablePlus.NodeType.LowerBound, lMove, lZobristHash); NagCoordinator.Abort(depth); return(beta); } alpha = lScore; lFlag = TranspositionTablePlus.NodeType.Exact; lBestMove = lMove; } } } if (lSuperKoCount == lMoves.Count) { NagCoordinator.Abort(depth); return(SearchInterface.Evaluate(playerToMove)); } TranspositionTable.Record(maxPly - depth, alpha, lFlag, lBestMove, lZobristHash); NagCoordinator.Abort(depth); return(alpha); }
// temp. for testing /// <summary> /// Launches the test. /// </summary> /// <returns></returns> public static int LaunchTest2() { GoBoard lGoBoard = new GoBoard(9); GameRecord lGameRecord = new GameRecord(); SGFCollection lSGFCollection = new SGFCollection(); lSGFCollection.LoadSGFFromMemory(SGFGameSamples.DYER); lSGFCollection.RetrieveGame(lGameRecord); GameRecordBoardAdapter.Apply(lGameRecord, lGoBoard, false); lGoBoard.Dump(); PatternCollection lPatternCollection = new PatternCollection(@"Patterns\test.db"); NagCoordinator lNagCoordinator = new NagCoordinator(9999, lPatternCollection); lNagCoordinator.Initialize(lGoBoard); ThreadPoolHelperWithParam<int>.Execute(LaunchWorker, 9999); ThreadPoolHelperWithParam<int>.Execute(LaunchWorker, 9999); ThreadPoolHelperWithParam<int>.Execute(LaunchWorker, 9999); ThreadPoolHelperWithParam<int>.Execute(LaunchWorker, 9999); Thread.Sleep(1000 * 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); Thread.Sleep(1000 * 300); return 0; }
// temp. for testing /// <summary> /// Launches the test. /// </summary> /// <returns></returns> public static int LaunchTest2() { GoBoard lGoBoard = new GoBoard(9); GameRecord lGameRecord = new GameRecord(); SGFCollection lSGFCollection = new SGFCollection(); lSGFCollection.LoadSGFFromMemory(SGFGameSamples.DYER); lSGFCollection.RetrieveGame(lGameRecord); GameRecordBoardAdapter.Apply(lGameRecord, lGoBoard, false); lGoBoard.Dump(); PatternCollection lPatternCollection = new PatternCollection(@"Patterns\test.db"); NagCoordinator lNagCoordinator = new NagCoordinator(9999, lPatternCollection); lNagCoordinator.Initialize(lGoBoard); ThreadPoolHelperWithParam <int> .Execute(LaunchWorker, 9999); ThreadPoolHelperWithParam <int> .Execute(LaunchWorker, 9999); ThreadPoolHelperWithParam <int> .Execute(LaunchWorker, 9999); ThreadPoolHelperWithParam <int> .Execute(LaunchWorker, 9999); Thread.Sleep(1000 * 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); lNagCoordinator.CreateNagPoints(lGoBoard, -10000, 10000, Color.Black, 30, 0, 0, 1); Thread.Sleep(1000 * 300); return(0); }