Пример #1
0
 public SearchResult(int node, Move move, TimeSpan time)
 {
     VisitedNode = node;
     BestMove    = move;
     Elapse      = time;
 }
Пример #2
0
        private int Negamax(int depth, int alpha, int beta, int color, bool debug, bool allowNull)
        {
            Stopwatch sw = null;

            if (depth == MaxDepth)
            {
                sw = new Stopwatch();
                sw.Start();
            }
            if (depth <= 0)
            {
                int score = Evaluate(color, debug, depth = 0);
                return(score);
            }
            //Null move
            if (allowNull)
            {
                int nullTurn  = -color;
                int nullValue = -Negamax(depth - 1 - 2, -beta, -beta + 1, nullTurn, debug, false);
                if (nullValue >= beta)
                {
                    return(nullValue); //Cut off
                }
            }

            List <Move> possibleMoves = null;

            possibleMoves = (debug) ? DebugLegalMoves() : examinedBoard.LegalMovesForPlayer(color);
            if (possibleMoves.Count == 0)
            {
                int score = Evaluate(color, debug, depth);
                return(score);
            }
            int  bestValue = Int32.MinValue;
            Move bestMove  = null;

            OrderMove(possibleMoves, depth);
            foreach (Move eleMove in possibleMoves)
            {
                visitedNode++;
                examinedBoard.MakeMove(eleMove);
                //Print information
                //Console.Write("\n" + new string('\t', MaxDepth - depth) + eleMove.ToString());
                int value = -Negamax(depth - 1, -beta, -alpha, -color, debug, nullPruning);
                examinedBoard.UndoMove(eleMove);
                //save hisEval
                if (depth == MaxDepth)
                {
                    hisEval[eleMove.ToString()] = value;
                }

                // We found a new max, also keep track of move
                if (value > bestValue)
                {
                    bestValue = value;
                    bestMove  = eleMove;
                }
                // If our max is greater than our lower bound, update our lower bound
                if (value > alpha)
                {
                    alpha = value;
                }

                // Alpha-beta pruning
                if (alpha >= beta)
                {
                    //Console.Write(new string('\t', MaxDepth - depth) + "Cut off");
                    //Save killer move
                    if (eleMove.Capture == '.')
                    {
                        searchKiller[MaxDepth - depth, 1] = searchKiller[MaxDepth - depth, 0];
                        searchKiller[MaxDepth - depth, 0] = eleMove;
                    }
                    //save history
                    SaveHistoryHeuristic(eleMove, depth);

                    break;
                }
            }
            if (depth == MaxDepth)
            {
                sw.Stop();
                Result = new SearchResult(visitedNode, bestMove, sw.Elapsed);
            }
            return(bestValue);
        }
Пример #3
0
        private MNResult AlphaBeta(int depth, int beta, int alpha, Move move, bool player, bool debug = false)
        {
            //BLACK is max player
            bool isMaxPlayer = (player == BLACK) ? true : false;

            if (depth == 0)
            {
                return(EvaluateNode(move, player, debug));
            }
            List <Move> possibleMoves = null;

            if (!debug)
            {
                possibleMoves = examinedBoard.PossibleMoves(player);
            }
            else
            {
                Console.Write("How many moves are there:");
                int count = Convert.ToInt32(Console.ReadLine());
                possibleMoves = new List <Move>();


                for (int i = 0; i < count; i++)
                {
                    Move debugMove = new Move(1, 4, 3, 4, this.examinedBoard);
                    possibleMoves.Add(debugMove);
                }
            }


            if (possibleMoves.Count == 0)
            {
                return(EvaluateNode(move, player, debug));
            }
            //sort later
            foreach (Move eleMove in possibleMoves)
            {
                examinedBoard.MakeMove(eleMove);
                bool     nextPlayer = !player;
                MNResult result     = AlphaBeta(depth - 1, beta, alpha, eleMove, nextPlayer, debug);
                int      value      = result.Value;

                examinedBoard.UndoMove(eleMove);
                //BLACK is Max Player
                if (isMaxPlayer)
                {
                    if (value > alpha) //Max Nodes can only make restriction on the lower bound
                    {
                        alpha = value;
                        if (depth == MaxDepth)
                        {
                            move = result.Move;
                        }
                    }
                }
                else
                {
                    if (value < beta)
                    {
                        beta = value;
                        if (depth == MaxDepth)
                        {
                            move = result.Move;
                        }
                    }
                }
                if (alpha >= beta) //pruning
                {
                    if (isMaxPlayer)
                    {
                        return(new MNResult(move, alpha));
                    }
                    else
                    {
                        return(new MNResult(move, beta));
                    }
                }
            }

            // Travel all child node, no prunning
            if (isMaxPlayer)
            {
                //value of node is alpha value
                return(new MNResult(move, alpha));
            }
            else
            {
                //value of min node is beta value
                return(new MNResult(move, beta));
            }
        }