public void RunUntil(int timeOut, bool earlyTimeOut) { DateTime lEndTime = DateTime.Now.AddSeconds(timeOut); while (true) { SearchStatus lSearchStatus = GetStatus(); SearchStatusType lSearchStatusType = lSearchStatus.Status; if ((lSearchStatusType == SearchStatusType.Completed) || (lSearchStatusType == SearchStatusType.Stopped)) { return; } // if it very unlike that another result will return in the remaining time, stop researching, so the time can be used later if (earlyTimeOut) { if ((lSearchStatusType == SearchStatusType.Thinking) && (lSearchStatus.BestMoveUpdate.Add(lSearchStatus.BestMoveUpdateTimeLapse).AddSeconds(-1) > lEndTime)) { Console.Error.WriteLine("Early Time Out:"); Console.Error.WriteLine("Saved: " + (lEndTime - DateTime.Now).Seconds.ToString() + " Seconds"); return; } } if (DateTime.Now > lEndTime) { return; } lock (SearchInterface) { Monitor.Wait(SearchInterface, 250); } } }
public MoveList SimpleSearch(Color playerToMove, bool endGame) { SearchOptions lSearchOptions = GetSearchOptions(playerToMove); lSearchOptions.IncludeEndGameMoves = endGame; if (endGame) { lSearchOptions.UsePatterns = false; } Board.Dump(); Console.Error.WriteLine("Move Search: "); Console.Error.WriteLine("Max Level: " + lSearchOptions.MaxPly.ToString() + " - Max Time: " + lSearchOptions.MaxSeconds.ToString() + " Alpha: " + lSearchOptions.AlphaValue.ToString() + " Beta: " + lSearchOptions.BetaValue.ToString()); Search.Start(Board, playerToMove, lSearchOptions, SearchMethodType, null); Search.RunUntil(lSearchOptions.MaxSeconds, lSearchOptions.EarlyTimeOut); SearchStatus lSearchStatus = Search.GetStatus(); Console.Error.WriteLine("Best Move: " + Board.Coord.ToString(lSearchStatus.BestMove) + " (" + lSearchStatus.BestValue.ToString() + ")"); Console.Error.WriteLine("Nodes: " + lSearchStatus.Nodes.ToString() + " - " + (lSearchStatus.Nodes / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second "); Console.Error.WriteLine("Evals: " + lSearchStatus.Evals.ToString() + " - " + (lSearchStatus.Evals / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("Total: " + (lSearchStatus.Evals + lSearchStatus.Nodes).ToString() + " - " + ((lSearchStatus.Evals + lSearchStatus.Nodes) / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("TT Hits: " + lSearchStatus.TranspositionTableHits.ToString() + " - " + (lSearchStatus.TranspositionTableHits / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("Time: " + (lSearchStatus.Timer.MilliSecondsElapsed / 1000.0).ToString() + " seconds"); if ((lSearchStatus.BestMove == CoordinateSystem.PASS) && (!endGame) && (!lSearchOptions.IncludeEndGameMoves)) { Console.Error.WriteLine("End Game Search:"); return(SimpleSearch(playerToMove, true)); } if (SearchOptions.PonderOnOpponentsTime) { Search.StartPonder(lSearchStatus.BestMove, playerToMove); } else if (!SearchOptions.ContinueThinkingAfterTimeOut) { Search.RequestStop(); } MoveList lMoveList = new MoveList(Board.BoardSize); lMoveList.Add(lSearchStatus.BestMove, lSearchStatus.BestValue); return(lMoveList); }
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; } } }
protected void UpdateStatus() { lock (this) { SearchStatus.Nodes = NodesSearched; SearchStatus.Evals = NodesEvaluated; SearchStatus.TranspositionTableHits = TranspositionTableHits; SearchStatus.Status = Status; SearchStatusCopy = SearchStatus.Clone(); UpdateStatusFlag = false; Monitor.PulseAll(this); } }
public SearchStatus Clone() { SearchStatus lSearchStatus = new SearchStatus(); lSearchStatus.Status = Status; lSearchStatus.BestMove = BestMove; lSearchStatus.BestValue = BestValue; lSearchStatus.Nodes = Nodes; lSearchStatus.Evals = Evals; lSearchStatus.CurrentPly = CurrentPly; lSearchStatus.MaxPly = MaxPly; lSearchStatus.PercentComplete = PercentComplete; lSearchStatus.EndGameMoves = EndGameMoves; lSearchStatus.BestMoveUpdate = BestMoveUpdate; lSearchStatus.BestMoveUpdateTimeLapse = BestMoveUpdateTimeLapse; lSearchStatus.TranspositionTableHits = TranspositionTableHits; lSearchStatus.BoardSize = BoardSize; lSearchStatus.Timer = Timer.Clone(); return lSearchStatus; }
public SearchStatus Clone() { SearchStatus lSearchStatus = new SearchStatus(); lSearchStatus.Status = Status; lSearchStatus.BestMove = BestMove; lSearchStatus.BestValue = BestValue; lSearchStatus.Nodes = Nodes; lSearchStatus.Evals = Evals; lSearchStatus.CurrentPly = CurrentPly; lSearchStatus.MaxPly = MaxPly; lSearchStatus.PercentComplete = PercentComplete; lSearchStatus.EndGameMoves = EndGameMoves; lSearchStatus.BestMoveUpdate = BestMoveUpdate; lSearchStatus.BestMoveUpdateTimeLapse = BestMoveUpdateTimeLapse; lSearchStatus.TranspositionTableHits = TranspositionTableHits; lSearchStatus.BoardSize = BoardSize; lSearchStatus.Timer = Timer.Clone(); return(lSearchStatus); }
public void Initialize(GoBoard goBoard, Color playerToMove, SearchOptions searchOptions, OnCompletion onCompletion) { lock (this) { SearchStatus = new SearchStatus(); SearchStatus.BoardSize = goBoard.BoardSize; Status = SearchStatusType.Thinking; UpdateStatus(); UpdateStatusFlag = true; StopThinkingFlag = false; SearchOptions = searchOptions.Clone(); NodesSearched = NodesEvaluated = 0; CheckSuperKo = searchOptions.CheckSuperKo; OnCompletion = onCompletion; SearchInterface.Initialize(goBoard, SearchOptions); Board = goBoard; PlayerToMove = playerToMove; } }
public void OnCompletion(SearchStatus searchStatus) { WorkerFunctions.Respond(Proxy, ID, (searchStatus.Status == SearchStatusType.Completed), CoordinateSystem.ToString2(searchStatus.BestMove, searchStatus.BoardSize) + "\t" + searchStatus.BestValue.ToString(), true); }
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); }