protected void Think(Color playerToMove) { PrincipalVariation = new PrincipalVariation(Board.BoardSize); FollowPV = true; TranspositionTableHits = 0; int lBestValue = 0; if (SearchOptions.IncludeEndGameMoves) { TranspositionTable = TranspositionTableEndGame; } else { TranspositionTable = TranspositionTablePrimary; } int lStart = (SearchOptions.StartPly <= SearchOptions.MaxPly) ? SearchOptions.StartPly : SearchOptions.MaxPly; if (lStart <= 0) { lStart = 1; } for (int lDepth = lStart; lDepth <= SearchOptions.MaxPly; lDepth++) { SearchComplete = true; FollowPV = true; lBestValue = Search(playerToMove, lDepth, 0, -10000, 10000); Console.Error.WriteLine("Ply: " + lDepth + " - " + SearchStatus.Timer.SecondsElapsed + " Seconds - Nodes/TT Hits: " + NodesSearched.ToString() + "/" + TranspositionTableHits.ToString() + " - Best: " + Board.Coord.ToString(PrincipalVariation.BestMove) + " (" + lBestValue + ")"); SearchStatus.UpdateBestMove(PrincipalVariation.BestMove, lBestValue); SearchStatus.CurrentPly = lDepth; SearchStatus.MaxPly = lDepth; SearchStatus.PercentComplete = (lDepth / SearchOptions.MaxPly) * 100; UpdateStatus(); if (StopThinkingFlag) { break; } if (SearchComplete) { Console.Error.WriteLine("Ply: " + lDepth + " - Search Completed!"); break; } } }
public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta) { if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } PrincipalVariation.SetPVLength(depth); MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); 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)) { PrincipalVariation.UpdatePV(depth, CoordinateSystem.PASS); NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } SearchInterface.SortMoveList(lMoves); if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } int lSuperKoCount = 0; foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAlphaBetaIterative.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 (lScore > alpha) { if (lScore >= beta) { return(beta); } alpha = lScore; PrincipalVariation.UpdatePV(depth, lMove); if (depth == 0) { if (lScore > SearchStatus.BestValue) { SearchStatus.UpdateBestMove(lMove, lScore); } Console.Error.WriteLine("Move: " + Board.Coord.ToString(lMove) + " (" + lScore.ToString() + ")"); } } } } if (lSuperKoCount == lMoves.Count) { return(SearchInterface.Evaluate(playerToMove)); } return(alpha); }
protected int Search(Color playerToMove, int maxPly, int depth) { if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); 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)) { NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } int lSuperKoCount = 0; int lBest = Int32.MinValue; int lBestMove = CoordinateSystem.PASS; // dummy value foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAlphaBetaIterative.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1); Board.Undo(); if (depth == 0) { MoveList.Add(lMove, lScore); if (lScore > SearchStatus.BestValue) { SearchStatus.UpdateBestMove(lMove, lScore); } Console.Error.WriteLine("# " + MoveList.Count + " - Move: " + Board.Coord.ToString(lMove) + " (" + lScore.ToString() + ")"); } if (lScore > lBest) { lBest = lScore; lBestMove = lMove; } } } if (lSuperKoCount == lMoves.Count) { return(SearchInterface.Evaluate(playerToMove)); } return(lBest); }