Exemplo n.º 1
0
        public int CompareTo(object obj)
        {
            ZobristHash lZobristHash = (ZobristHash)obj;

            if (lZobristHash == this)
            {
                return(0);
            }
            else
            {
                return(-1);
            }
        }
Exemplo n.º 2
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;
        }
        public Node Retrieve(ZobristHash zobristKey)
        {
            Node lEntry = Table[(int)zobristKey.HashValue % TableSize];

            if (lEntry.Flag != NodeType.Unknown)
            {
                if (lEntry.ZobristKey == zobristKey.HashValue)
                {
                    return(lEntry);
                }
            }

            return(EmptyNode);
        }
Exemplo n.º 4
0
        public NagNode(GoBoard goBoard, int alpha, int beta, Color playerToMove, int startDepth, int depth, int permutationNbr)
        {
            foreach (KeyValuePair<Color, int> lMove in goBoard.MoveList)
                MoveList.Add(new KeyValuePair<Color, int>(lMove.Key, lMove.Value));

            Alpha = alpha;
            Beta = beta;
            PlayerToMove = playerToMove;
            Depth = depth;
            ZobristHash = goBoard.ZobristHash.Clone();
            NarrowedAlpha = alpha;
            NarrowedBeta = beta;
            StartDepth = startDepth;
            PermutationNbr = 1;
        }
Exemplo n.º 5
0
        protected ZobristHash ComputeZobrist(Pattern pattern, Color color)
        {
            int lSize = pattern.GetFullBoardSize();

            ZobristHash lZobristHash = new ZobristHash();

            for (int x = 0; x < lSize; x++)
                for (int y = 0; y < lSize; y++)
                    switch (pattern.GetCell(x, y))
                    {
                        case 'X': lZobristHash.Delta(color.IsBlack ? Color.Black : Color.White, CoordinateSystem.At(x, y, lSize)); break;
                        case 'O': lZobristHash.Delta(color.IsBlack ? Color.White : Color.Black, CoordinateSystem.At(x, y, lSize)); break;
                    }

            return lZobristHash;
        }
Exemplo n.º 6
0
        public NagNode(GoBoard goBoard, int alpha, int beta, Color playerToMove, int startDepth, int depth, int permutationNbr)
        {
            foreach (KeyValuePair <Color, int> lMove in goBoard.MoveList)
            {
                MoveList.Add(new KeyValuePair <Color, int>(lMove.Key, lMove.Value));
            }

            Alpha          = alpha;
            Beta           = beta;
            PlayerToMove   = playerToMove;
            Depth          = depth;
            ZobristHash    = goBoard.ZobristHash.Clone();
            NarrowedAlpha  = alpha;
            NarrowedBeta   = beta;
            StartDepth     = startDepth;
            PermutationNbr = 1;
        }
        protected ZobristHash ComputeZobrist(Pattern pattern, Color color)
        {
            int lSize = pattern.GetFullBoardSize();

            ZobristHash lZobristHash = new ZobristHash();

            for (int x = 0; x < lSize; x++)
            {
                for (int y = 0; y < lSize; y++)
                {
                    switch (pattern.GetCell(x, y))
                    {
                    case 'X': lZobristHash.Delta(color.IsBlack ? Color.Black : Color.White, CoordinateSystem.At(x, y, lSize)); break;

                    case 'O': lZobristHash.Delta(color.IsBlack ? Color.White : Color.Black, CoordinateSystem.At(x, y, lSize)); break;
                    }
                }
            }

            return(lZobristHash);
        }
Exemplo n.º 8
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);
        }
        public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta)
        {
            ZobristHash lZobristHash = Board.ZobristHash.Clone();

            lZobristHash.Mark(playerToMove);

            if (depth > 1)
            {
                TranspositionTable.Node lNode = TranspositionTable.Retrieve(lZobristHash);

                if ((lNode.Flag != TranspositionTable.NodeType.Unknown) && ((maxPly - depth) <= lNode.Height))
                {
                    switch (lNode.Flag)
                    {
                    case TranspositionTable.NodeType.Exact:
                    {
                        SearchComplete = false;
                        TranspositionTableHits++;
                        return(lNode.Value);
                    }

                    case TranspositionTable.NodeType.LowerBound:
                    {
                        alpha = (alpha > lNode.Value) ? alpha : lNode.Value;
                        break;
                    }

                    case TranspositionTable.NodeType.UpperBound:
                    {
                        beta = (beta < lNode.Value) ? beta : lNode.Value;
                        break;
                    }
                    }

                    if (alpha >= beta)
                    {
                        return(lNode.Value);
                    }
                }
            }

            if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver())))
            {
                if (depth == maxPly)
                {
                    SearchComplete = false;
                }

                NodesEvaluated++;
                int lEval = SearchInterface.Evaluate(playerToMove);

                TranspositionTable.Record(maxPly - depth, lEval, TranspositionTable.NodeType.Exact, lZobristHash);

                return(lEval);
            }

            PrincipalVariation.SetPVLength(depth);

            MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves);

            SearchInterface.PruneMoveList(lMoves);

            SearchInterface.PrioritizeMoves(lMoves, playerToMove);

            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);

                int lEval = SearchInterface.Evaluate(playerToMove);
                TranspositionTable.Record(maxPly - depth, lEval, TranspositionTable.NodeType.Exact, lZobristHash);
                return(lEval);
            }

            // follow the principle variation
            if (FollowPV)
            {
                FollowPV = false;

                int lPVMove = PrincipalVariation.GetMove(depth);

                if (lPVMove != PrincipalVariation.NO_VALUE)
                {
                    if (lMoves.Contains(lPVMove))
                    {
                        lMoves.SetValue(lPVMove, Int32.MaxValue);
                        FollowPV = true;
                    }
                }
            }

            SearchInterface.SortMoveList(lMoves);

            if (UpdateStatusFlag)
            {
                UpdateStatus();
            }

            if (StopThinkingFlag)
            {
                Stop();
            }

            int lSuperKoCount = 0;

            TranspositionTable.NodeType lFlag = TranspositionTable.NodeType.UpperBound;

            foreach (int lMove in lMoves)
            {
                NodesSearched++;

                bool lPlayed = Board.PlayStone(lMove, playerToMove, true);

                if (!lPlayed)
                {
                    throw new ApplicationException("SearchMethodAB_ID_TT_PVS.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)
                        {
                            TranspositionTable.Record(maxPly - depth, alpha, TranspositionTable.NodeType.LowerBound, lZobristHash);
                            return(lScore);
                        }

                        alpha = lScore;
                        lFlag = TranspositionTable.NodeType.Exact;
                        PrincipalVariation.UpdatePV(depth, lMove);
                    }
                }
            }

            if (lSuperKoCount == lMoves.Count)
            {
                return(SearchInterface.Evaluate(playerToMove));
            }

            TranspositionTable.Record(maxPly - depth, alpha, lFlag, lZobristHash);

            return(alpha);
        }
Exemplo n.º 10
0
        public void Record(int height, int value, NodeType flag, int move, ZobristHash zobristKey)
        {
            int lIndex = (int)zobristKey.HashValue % TableSize;

            bool lReplace = true;

            if (Table[lIndex].Flag != NodeType.Unknown)
                if (Table[lIndex].ZobristKey == zobristKey.HashValue)
                    if (height <= Table[lIndex].Height)
                        lReplace = false;

            if (lReplace)
            {
                Table[lIndex].ZobristKey = zobristKey.HashValue;
                Table[lIndex].Value = value;
                Table[lIndex].Height = (byte)height;
                Table[lIndex].Flag = flag;
                Table[lIndex].Move = move;
            }
        }
Exemplo n.º 11
0
        public Node Retrieve(ZobristHash zobristKey)
        {
            Node lEntry = Table[(int)zobristKey.HashValue % TableSize];

            if (lEntry.Flag != NodeType.Unknown)
                if (lEntry.ZobristKey == zobristKey.HashValue)
                    return lEntry;

            return EmptyNode;
        }
Exemplo n.º 12
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;
        }
Exemplo n.º 13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZobristHash"/> class.
 /// </summary>
 /// <param name="lZobristHash">Zobrist Hash.</param>
 protected ZobristHash(ZobristHash lZobristHash)
 {
     HashKey = lZobristHash.HashKey;
 }
Exemplo n.º 14
0
        protected void Clear()
        {
            AllBlocks = new List<GoBlockBase>();

            GoEmptyBlock lEmptyBlock = new GoEmptyBlock(this);

            UndoStack = new UndoStack(this);

            Turn = Color.Black;
            ZobrishHashes = new Dictionary<ZobristHash, int>();
            LastMove = CoordinateSystem.PASS;
            MoveList = new List<KeyValuePair<Color, int>>();
            SimpleKoPoint = CoordinateSystem.PASS;
            MoveNbr = 0;
            Komi = 0;
            GameOver = false;
            CapturedStoneCnt = new int[2];
            ColorEnclosedRegions = null;
            SafetyStatusMap = null;

            ZobristHash = new ZobristHash();
            Cells = new GoCell[Coord.BoardArea];

            for (int i = 0; i < Coord.BoardArea; i++)
                Cells[i] = new GoCell(i, this, lEmptyBlock);

            for (int i = 0; i < Coord.BoardArea; i++)
                Cells[i].SetNeighbors();
        }
Exemplo n.º 15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZobristHash"/> class.
 /// </summary>
 /// <param name="lZobristHash">Zobrist Hash.</param>
 protected ZobristHash(ZobristHash lZobristHash)
 {
     HashKey = lZobristHash.HashKey;
 }