コード例 #1
0
        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);
                }
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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;
                }
            }
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
ファイル: SearchStatus.cs プロジェクト: tgiphil/GoTraxx
        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;
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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;
            }
        }
コード例 #8
0
ファイル: WorkerFunctions.cs プロジェクト: tgiphil/GoTraxx
 public void OnCompletion(SearchStatus searchStatus)
 {
     WorkerFunctions.Respond(Proxy, ID, (searchStatus.Status == SearchStatusType.Completed), CoordinateSystem.ToString2(searchStatus.BestMove, searchStatus.BoardSize) + "\t" + searchStatus.BestValue.ToString(), true);
 }
コード例 #9
0
ファイル: SearchMethod.cs プロジェクト: tgiphil/GoTraxx
        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);
            }
        }
コード例 #10
0
ファイル: SearchMethod.cs プロジェクト: tgiphil/GoTraxx
        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;
            }
        }
コード例 #11
0
 public void OnCompletion(SearchStatus searchStatus)
 {
     WorkerFunctions.Respond(Proxy, ID, (searchStatus.Status == SearchStatusType.Completed), CoordinateSystem.ToString2(searchStatus.BestMove, searchStatus.BoardSize) + "\t" + searchStatus.BestValue.ToString(), true);
 }
コード例 #12
0
        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);
        }
コード例 #13
0
        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);
        }