Esempio n. 1
0
        /// <summary>
        /// AlphaBeta algorithm.Calculates best line in given depth
        /// </summary>
        /// <param name="alpha">Lowest value</param>
        /// <param name="beta">highest value</param>
        /// <param name="ply"></param>
        /// <param name="depth"></param>
        /// <param name="pv">Holds principal variation</param>
        /// <param name="nullmove"></param>
        /// <param name="nodeCount">Holds value of calculated moves</param>
        /// <returns>Returning value is the score of best line</returns>
        int AlphaBeta(int alpha, int beta, int ply, int depth, List <Move> pv, NullMove nullmove, ref int nodeCount)
        {
            //if time out or exit requested after 1st iteration,so leave thinking.
            if ((!HaveTime() || Exit) && iterationPly > 1)
            {
                return(0);
            }
            nodeCount++;

            var moves = Board.GenerateMoves();

            if (!moves.Any())
            {
                return(-Board.GetCheckMateOrStaleMateScore(ply));
            }
            if (ply <= 0)
            {
                return(QuiescenceSearch(alpha, beta, ref nodeCount));
            }
            var localpv  = new List <Move>();
            var pvSearch = false;

            #region Null Move Prunning
            if (nullmove == NullMove.Enabled && !Board.IsInCheck())
            {
                int R = 2;
                Board.ToggleSide();
                int score = -AlphaBeta(-beta, -beta + 1, ply - 1 - R, depth + 1, localpv, NullMove.Disabled, ref nodeCount);
                Board.ToggleSide();
                if (score >= beta)
                {
                    return(score);
                }
            }
            #endregion
            var sortedMoves = SortMoves(moves, depth);
            foreach (var move in sortedMoves)
            {
                Board.MakeMove(move);
                int score;
                if (Board.threeFoldRepetetion.IsThreeFoldRepetetion)
                {
                    score = Board.Draw;
                }
                else
                {
                    #region Late Move Reduction

                    if (!Board.IsInCheck())
                    {
                        score = -AlphaBeta(-alpha - 1, -alpha, ply - 2, depth + 1, localpv, NullMove.Enabled, ref nodeCount);
                    }
                    else
                    {
                        score = alpha + 1;
                    }
                    #endregion
                    if (score > alpha)
                    {
                        if (pvSearch)
                        {
                            score = -AlphaBeta(-alpha - 1, -alpha, ply - 1, depth + 1, localpv, NullMove.Enabled, ref nodeCount);

                            if (score > alpha && score < beta)
                            {
                                score = -AlphaBeta(-beta, -alpha, ply - 1, depth + 1, localpv, NullMove.Enabled, ref nodeCount);
                            }
                        }
                        else
                        {
                            score = -AlphaBeta(-beta, -alpha, ply - 1, depth + 1, localpv, NullMove.Enabled, ref nodeCount);
                        }
                    }
                }



                Board.TakeBackMove(move);

                if (score >= beta)
                {
                    killerMoves.Add(move, depth);

                    return(beta);//beta cut-off
                }
                if (score > alpha)
                {
                    historyMoves.AddMove(move);
                    pvSearch = true;
                    alpha    = score;

                    pv.Clear();
                    pv.Add(move);
                    pv.AddRange(localpv);
                }
            }
            return(alpha);
        }