Пример #1
0
 public void Start(NagNode nagNode, int boardSize)
 {
     BoardSize      = boardSize;
     NagNode        = nagNode;
     NagNode.Worker = this;
     Start(nagNode.PlayerToMove, nagNode.MoveList, nagNode.Depth, nagNode.Alpha, nagNode.Beta, nagNode.PermutationNbr);
 }
        public void NewNagPoint(NagNode nagNode)
        {
            lock (this)
            {
                AvailableNagNodes.Add(nagNode);
            }

            InstructWorkers();
        }
Пример #3
0
 public void Disconnect()
 {
     lock (this)
     {
         Console.Error.WriteLine("STATUS: Disconnecting Connection");
         State   = ConnectionState.Disconnecting;
         NagNode = null;
         NagCoordinator.Disconnected(this);
         Worker.Disconnect(true);
     }
 }
Пример #4
0
        public NagNode(NagNode nagNode, int permutationNbr)
        {
            MoveList = nagNode.MoveList;

            Alpha = nagNode.Alpha;
            Beta = nagNode.Beta;
            PlayerToMove = nagNode.PlayerToMove;
            Depth = nagNode.Depth;
            ZobristHash = nagNode.ZobristHash;
            NarrowedAlpha = nagNode.NarrowedAlpha;
            NarrowedBeta = nagNode.NarrowedBeta;
            StartDepth = nagNode.StartDepth;
            PermutationNbr = permutationNbr;
        }
Пример #5
0
        public NagNode(NagNode nagNode, int permutationNbr)
        {
            MoveList = nagNode.MoveList;

            Alpha          = nagNode.Alpha;
            Beta           = nagNode.Beta;
            PlayerToMove   = nagNode.PlayerToMove;
            Depth          = nagNode.Depth;
            ZobristHash    = nagNode.ZobristHash;
            NarrowedAlpha  = nagNode.NarrowedAlpha;
            NarrowedBeta   = nagNode.NarrowedBeta;
            StartDepth     = nagNode.StartDepth;
            PermutationNbr = permutationNbr;
        }
        protected bool IsStillValid(NagNode lNagNode)
        {
            lock (this)
            {
                List <NagNode> lNagNodes = NagNodeByDepth[lNagNode.StartDepth];

                if (lNagNodes == null)
                {
                    return(false);
                }

                return(lNagNodes.Contains(lNagNode));
            }
        }
        public void WorkerResult(NagNode nagNode)
        {
            lock (this)
            {
                // note: unless nag results might be put on this list
                // so the results need to be rechecked later

                Results.Add(nagNode);
            }

            if (OnNag != null)
            {
                OnNag();                 // tell search that results are available
            }
        }
Пример #8
0
        public void Abort()
        {
            lock (this)
            {
                if (State == ConnectionState.Ready)
                {
                    return;
                }

                if (State != ConnectionState.Thinking)
                {
                    return;
                }

                State   = ConnectionState.Aborting;
                NagNode = null;

                SendCommand("abort", FormatIdNbr(++CommandNbr, 1));
            }
        }
Пример #9
0
        public void Initalize(int boardSize)
        {
            lock (this)
            {
                if (State == ConnectionState.Thinking)
                {
                    Abort();
                    return;
                }

                if (!((State == ConnectionState.Available) || (State == ConnectionState.Ready)))
                {
                    return;
                }

                NagNode = null;
                State   = ConnectionState.Initializing;
                CommandNbr++;

                SendCommand("set_boardsize", FormatIdNbr(CommandNbr, 1), boardSize);
            }
        }
        public void CreateNagPoints(GoBoard goBoard, int alpha, int beta, Color playerToMove, int depth, int maxDepth, int moves, int maxNags)
        {
            int lLevels = maxDepth - depth;

            if (lLevels < 3)                    // avoid shallow searches
            {
                return;
            }

            int lAvailableWorkersCount = AvailableWorkersCount;

            if (lAvailableWorkersCount == 0)
            {
                return;
            }

            List <NagNode> lNagNodes = null;

            lock (this)
            {
                lNagNodes = new List <NagNode>();

                NagNode lNagNode = new NagNode(goBoard, alpha, beta, playerToMove, depth, maxDepth - depth, Random.Next(9) + 1);
                lNagNodes.Add(lNagNode);

                int lNew = Math.Min(Math.Min(lAvailableWorkersCount - 1, moves), maxNags - 1);

                for (int i = 0; i < lNew; i++)
                {
                    NagNode lNagNode2 = new NagNode(lNagNode, Random.Next(9) + 1);
                    lNagNodes.Add(lNagNode2);
                }

                NagNodeByDepth[depth] = lNagNodes;
            }

            NewNagPoints(lNagNodes);
        }
        protected void InstructWorkersThread()
        {
            lock (this)
            {
                while (AvailableWorkers.Count != 0)
                {
                    if (AvailableNagNodes.Count == 0)
                    {
                        return;
                    }

                    int lIndex = Random.Next(AvailableNagNodes.Count);

                    WorkerProxy lWorkerProxy = AvailableWorkers[0];
                    NagNode     lNagNode     = AvailableNagNodes[lIndex];

                    AvailableWorkers.RemoveAt(0);
                    AvailableNagNodes.RemoveAt(lIndex);

                    lWorkerProxy.Start(lNagNode, BoardSize);
                }
            }
        }
Пример #12
0
        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);
        }
Пример #13
0
        public void Abort()
        {
            lock (this)
            {
                if (State == ConnectionState.Ready)
                    return;

                if (State != ConnectionState.Thinking)
                    return;

                State = ConnectionState.Aborting;
                NagNode = null;

                SendCommand("abort", FormatIdNbr(++CommandNbr, 1));
            }
        }
Пример #14
0
 public void Start(NagNode nagNode, int boardSize)
 {
     BoardSize = boardSize;
     NagNode = nagNode;
     NagNode.Worker = this;
     Start(nagNode.PlayerToMove, nagNode.MoveList, nagNode.Depth, nagNode.Alpha, nagNode.Beta, nagNode.PermutationNbr);
 }
Пример #15
0
        public void ProcesLine(string line)
        {
            if (line == null)
            {
                Disconnect();
                return;
            }

            string lLine = line.TrimEnd('\n');
            string[] lCmds = lLine.Split('\t');
            bool lAsync = (lCmds[0][0] == '!');
            bool lSuccess = (lCmds[0][lAsync ? 1 : 0] == '=');

            string[] lID = lCmds[1].Split('.');
            int lCommandNbr = Convert.ToInt32(lID[0]);
            int lSeqNbr = Convert.ToInt32(lID[1]);

            if ((Verbose) && (lCmds.Length > 3))
                Console.Error.WriteLine("STATUS: P< " + lLine);

            lock (this)
            {
                if ((lCommandNbr == 0) && (lSeqNbr == 0) && (!lSuccess))
                {
                    // worker disconnecting...
                    Disconnect();
                    return;
                }

                if (State == ConnectionState.Negotiating)
                {
                    if ((!lSuccess) || (lCmds[2] != "1.0"))
                    {
                        Disconnect();
                        return;
                    }

                    if (lSeqNbr == 1)
                    {
                        State = ConnectionState.Negotiated;
                        ThreadPoolHelperWithParam<WorkerProxy>.Execute(NagCoordinator.WorkerNegotiated, this);
                        //NagCoordinator.WorkerNegotiated(this);
                    }
                }
                else if (State == ConnectionState.SendingPatterns)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            Disconnect();
                            return;
                        }

                        if (lSeqNbr == 1)
                        {
                            State = ConnectionState.Available;
                            ThreadPoolHelperWithParam<WorkerProxy>.Execute(NagCoordinator.WorkerAvailable, this);
                            //NagCoordinator.WorkerAvailable(this);
                        }
                    }
                }
                else if (State == ConnectionState.Initializing)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            // error with commands, disconnect to reset worker
                            Disconnect();
                            return;
                        }

                        if (lSeqNbr == 1)
                        {
                            State = ConnectionState.Ready;
                            ThreadPoolHelperWithParam<WorkerProxy>.Execute(NagCoordinator.WorkerReady, this);
                            //						NagCoordinator.WorkerReady(this);
                        }
                    }
                }
                else if (State == ConnectionState.Thinking)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            // error with commands, disconnect to reset worker
                            Disconnect();
                            return;
                        }

                        if ((lSeqNbr == 6) && (lAsync))
                        {

                            State = ConnectionState.Ready;
                            if (NagNode != null)
                            {
                                NagNode.SetResult(Convert.ToInt32(lCmds[3]), CoordinateSystem.At(lCmds[2], BoardSize));
                                ThreadPoolHelperWithParam<NagNode>.Execute(NagCoordinator.WorkerResult, NagNode);
                                NagNode = null;
                            }

                            ThreadPoolHelperWithParam<WorkerProxy>.Execute(NagCoordinator.WorkerReady, this);
                        }
                    }
                }
                else if (State == ConnectionState.Aborting)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            // error with commands, disconnect to reset worker
                            Disconnect();
                            return;
                        }

                        if (lSeqNbr == 1)
                        {
                            State = ConnectionState.Ready;
                            NagNode = null;
                            ThreadPoolHelperWithParam<WorkerProxy>.Execute(NagCoordinator.WorkerReady, this);
                        }
                    }
                }
            }
        }
Пример #16
0
        public void Initalize(int boardSize)
        {
            lock (this)
            {
                if (State == ConnectionState.Thinking)
                {
                    Abort();
                    return;
                }

                if (!((State == ConnectionState.Available) || (State == ConnectionState.Ready)))
                    return;

                NagNode = null;
                State = ConnectionState.Initializing;
                CommandNbr++;

                SendCommand("set_boardsize", FormatIdNbr(CommandNbr, 1), boardSize);
            }
        }
Пример #17
0
 public void Disconnect()
 {
     lock (this)
     {
         Console.Error.WriteLine("STATUS: Disconnecting Connection");
         State = ConnectionState.Disconnecting;
         NagNode = null;
         NagCoordinator.Disconnected(this);
         Worker.Disconnect(true);
     }
 }
Пример #18
0
        public void ProcesLine(string line)
        {
            if (line == null)
            {
                Disconnect();
                return;
            }

            string lLine = line.TrimEnd('\n');

            string[] lCmds    = lLine.Split('\t');
            bool     lAsync   = (lCmds[0][0] == '!');
            bool     lSuccess = (lCmds[0][lAsync ? 1 : 0] == '=');

            string[] lID         = lCmds[1].Split('.');
            int      lCommandNbr = Convert.ToInt32(lID[0]);
            int      lSeqNbr     = Convert.ToInt32(lID[1]);

            if ((Verbose) && (lCmds.Length > 3))
            {
                Console.Error.WriteLine("STATUS: P< " + lLine);
            }

            lock (this)
            {
                if ((lCommandNbr == 0) && (lSeqNbr == 0) && (!lSuccess))
                {
                    // worker disconnecting...
                    Disconnect();
                    return;
                }

                if (State == ConnectionState.Negotiating)
                {
                    if ((!lSuccess) || (lCmds[2] != "1.0"))
                    {
                        Disconnect();
                        return;
                    }

                    if (lSeqNbr == 1)
                    {
                        State = ConnectionState.Negotiated;
                        ThreadPoolHelperWithParam <WorkerProxy> .Execute(NagCoordinator.WorkerNegotiated, this);

                        //NagCoordinator.WorkerNegotiated(this);
                    }
                }
                else if (State == ConnectionState.SendingPatterns)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            Disconnect();
                            return;
                        }

                        if (lSeqNbr == 1)
                        {
                            State = ConnectionState.Available;
                            ThreadPoolHelperWithParam <WorkerProxy> .Execute(NagCoordinator.WorkerAvailable, this);

                            //NagCoordinator.WorkerAvailable(this);
                        }
                    }
                }
                else if (State == ConnectionState.Initializing)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            // error with commands, disconnect to reset worker
                            Disconnect();
                            return;
                        }

                        if (lSeqNbr == 1)
                        {
                            State = ConnectionState.Ready;
                            ThreadPoolHelperWithParam <WorkerProxy> .Execute(NagCoordinator.WorkerReady, this);

                            //						NagCoordinator.WorkerReady(this);
                        }
                    }
                }
                else if (State == ConnectionState.Thinking)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            // error with commands, disconnect to reset worker
                            Disconnect();
                            return;
                        }

                        if ((lSeqNbr == 6) && (lAsync))
                        {
                            State = ConnectionState.Ready;
                            if (NagNode != null)
                            {
                                NagNode.SetResult(Convert.ToInt32(lCmds[3]), CoordinateSystem.At(lCmds[2], BoardSize));
                                ThreadPoolHelperWithParam <NagNode> .Execute(NagCoordinator.WorkerResult, NagNode);

                                NagNode = null;
                            }

                            ThreadPoolHelperWithParam <WorkerProxy> .Execute(NagCoordinator.WorkerReady, this);
                        }
                    }
                }
                else if (State == ConnectionState.Aborting)
                {
                    if (CommandNbr == lCommandNbr)
                    {
                        if (!lSuccess)
                        {
                            // error with commands, disconnect to reset worker
                            Disconnect();
                            return;
                        }

                        if (lSeqNbr == 1)
                        {
                            State   = ConnectionState.Ready;
                            NagNode = null;
                            ThreadPoolHelperWithParam <WorkerProxy> .Execute(NagCoordinator.WorkerReady, this);
                        }
                    }
                }
            }
        }
Пример #19
0
        public void CreateNagPoints(GoBoard goBoard, int alpha, int beta, Color playerToMove, int depth, int maxDepth, int moves, int maxNags)
        {
            int lLevels = maxDepth - depth;

            if (lLevels < 3)	// avoid shallow searches
                return;

            int lAvailableWorkersCount = AvailableWorkersCount;

            if (lAvailableWorkersCount == 0)
                return;

            List<NagNode> lNagNodes = null;

            lock (this)
            {
                lNagNodes = new List<NagNode>();

                NagNode lNagNode = new NagNode(goBoard, alpha, beta, playerToMove, depth, maxDepth - depth, Random.Next(9) + 1);
                lNagNodes.Add(lNagNode);

                int lNew = Math.Min(Math.Min(lAvailableWorkersCount - 1, moves), maxNags - 1);

                for (int i = 0; i < lNew; i++)
                {
                    NagNode lNagNode2 = new NagNode(lNagNode, Random.Next(9) + 1);
                    lNagNodes.Add(lNagNode2);
                }

                NagNodeByDepth[depth] = lNagNodes;
            }

            NewNagPoints(lNagNodes);
        }
Пример #20
0
        public void NewNagPoint(NagNode nagNode)
        {
            lock (this)
            {
                AvailableNagNodes.Add(nagNode);
            }

            InstructWorkers();
        }
Пример #21
0
        public void WorkerResult(NagNode nagNode)
        {
            lock (this)
            {
                // note: unless nag results might be put on this list
                // so the results need to be rechecked later

                Results.Add(nagNode);
            }

            if (OnNag != null)
                OnNag(); // tell search that results are available
        }
Пример #22
0
        protected bool IsStillValid(NagNode lNagNode)
        {
            lock (this)
            {
                List<NagNode> lNagNodes = NagNodeByDepth[lNagNode.StartDepth];

                if (lNagNodes == null)
                    return false;

                return lNagNodes.Contains(lNagNode);
            }
        }