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;
                }
            }
        }
Exemple #2
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);
        }
Exemple #3
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);
        }