Ejemplo n.º 1
0
        private static int CalculatePawnScores(ChessBoard cb)
        {
            var score = 0;

            // penalty for doubled pawns
            for (var i = 0; i < 8; i++)
            {
                if (BitOperations.PopCount((ulong)(cb.Pieces[White][Pawn] & Bitboard.Files[i])) > 1)
                {
                    score -= EvalConstants.PawnScores[EvalConstants.IxPawnDouble];
                }

                if (BitOperations.PopCount((ulong)(cb.Pieces[Black][Pawn] & Bitboard.Files[i])) > 1)
                {
                    score += EvalConstants.PawnScores[EvalConstants.IxPawnDouble];
                }
            }

            // bonus for connected pawns
            var pawns = Bitboard.GetWhitePawnAttacks(cb.Pieces[White][Pawn]) & cb.Pieces[White][Pawn];

            while (pawns != 0)
            {
                score += EvalConstants.PawnConnected[BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            pawns = Bitboard.GetBlackPawnAttacks(cb.Pieces[Black][Pawn]) & cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                score -= EvalConstants.PawnConnected[7 - BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            // bonus for neighbour pawns
            pawns = Bitboard.GetPawnNeighbours(cb.Pieces[White][Pawn]) & cb.Pieces[White][Pawn];
            while (pawns != 0)
            {
                score += EvalConstants.PawnNeighbour[BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            pawns = Bitboard.GetPawnNeighbours(cb.Pieces[Black][Pawn]) & cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                score -= EvalConstants.PawnNeighbour[7 - BitOperations.TrailingZeroCount(pawns) / 8];
                pawns &= pawns - 1;
            }

            // set outposts
            cb.PassedPawnsAndOutposts = 0;
            pawns = Bitboard.GetWhitePawnAttacks(cb.Pieces[White][Pawn]) & ~cb.Pieces[White][Pawn] &
                    ~cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                if ((Bitboard.GetWhiteAdjacentMask(BitOperations.TrailingZeroCount(pawns)) & cb.Pieces[Black][Pawn]) ==
                    0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                pawns &= pawns - 1;
            }

            pawns = Bitboard.GetBlackPawnAttacks(cb.Pieces[Black][Pawn]) & ~cb.Pieces[White][Pawn] &
                    ~cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                if ((Bitboard.GetBlackAdjacentMask(BitOperations.TrailingZeroCount(pawns)) & cb.Pieces[White][Pawn]) ==
                    0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                pawns &= pawns - 1;
            }

            int index;

            // white
            pawns = cb.Pieces[White][Pawn];
            while (pawns != 0)
            {
                index = BitOperations.TrailingZeroCount(pawns);

                // isolated pawns
                if ((Bitboard.FilesAdjacent[index & 7] & cb.Pieces[White][Pawn]) == 0)
                {
                    score -= EvalConstants.PawnScores[EvalConstants.IxPawnIsolated];
                }

                // backward pawns
                else if ((Bitboard.GetBlackAdjacentMask(index + 8) & cb.Pieces[White][Pawn]) == 0)
                {
                    if ((StaticMoves.PawnAttacks[White][index + 8] & cb.Pieces[Black][Pawn]) != 0)
                    {
                        if ((Bitboard.Files[index & 7] & cb.Pieces[Black][Pawn]) == 0)
                        {
                            score -= EvalConstants.PawnScores[EvalConstants.IxPawnBackward];
                        }
                    }
                }

                // pawn defending 2 pawns
                if (BitOperations.PopCount((ulong)(StaticMoves.PawnAttacks[White][index] & cb.Pieces[White][Pawn])) ==
                    2)
                {
                    score -= EvalConstants.PawnScores[EvalConstants.IxPawnInverse];
                }

                // set passed pawns
                if ((Bitboard.GetWhitePassedPawnMask(index) & cb.Pieces[Black][Pawn]) == 0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                // candidate passed pawns (no pawns in front, more friendly pawns behind and adjacent than enemy pawns)
                else if (63 - BitOperations.LeadingZeroCount(
                             (ulong)((cb.Pieces[White][Pawn] | cb.Pieces[Black][Pawn]) &
                                     Bitboard.Files[index & 7])) == index)
                {
                    if (BitOperations.PopCount((ulong)(cb.Pieces[White][Pawn] &
                                                       Bitboard.GetBlackPassedPawnMask(index + 8))) >=
                        BitOperations.PopCount(
                            (ulong)(cb.Pieces[Black][Pawn] & Bitboard.GetWhitePassedPawnMask(index))))
                    {
                        score += EvalConstants.PassedCandidate[index / 8];
                    }
                }

                pawns &= pawns - 1;
            }

            // black
            pawns = cb.Pieces[Black][Pawn];
            while (pawns != 0)
            {
                index = BitOperations.TrailingZeroCount(pawns);

                // isolated pawns
                if ((Bitboard.FilesAdjacent[index & 7] & cb.Pieces[Black][Pawn]) == 0)
                {
                    score += EvalConstants.PawnScores[EvalConstants.IxPawnIsolated];
                }

                // backward pawns
                else if ((Bitboard.GetWhiteAdjacentMask(index - 8) & cb.Pieces[Black][Pawn]) == 0)
                {
                    if ((StaticMoves.PawnAttacks[Black][index - 8] & cb.Pieces[White][Pawn]) != 0)
                    {
                        if ((Bitboard.Files[index & 7] & cb.Pieces[White][Pawn]) == 0)
                        {
                            score += EvalConstants.PawnScores[EvalConstants.IxPawnBackward];
                        }
                    }
                }

                // pawn defending 2 pawns
                if (BitOperations.PopCount((ulong)(StaticMoves.PawnAttacks[Black][index] & cb.Pieces[Black][Pawn])) ==
                    2)
                {
                    score += EvalConstants.PawnScores[EvalConstants.IxPawnInverse];
                }

                // set passed pawns
                if ((Bitboard.GetBlackPassedPawnMask(index) & cb.Pieces[White][Pawn]) == 0)
                {
                    cb.PassedPawnsAndOutposts |= pawns & -pawns;
                }

                // candidate passers
                else if (BitOperations.TrailingZeroCount((cb.Pieces[White][Pawn] | cb.Pieces[Black][Pawn]) &
                                                         Bitboard.Files[index & 7]) == index)
                {
                    if (BitOperations.PopCount((ulong)(cb.Pieces[Black][Pawn] &
                                                       Bitboard.GetWhitePassedPawnMask(index - 8))) >=
                        BitOperations.PopCount(
                            (ulong)(cb.Pieces[White][Pawn] & Bitboard.GetBlackPassedPawnMask(index))))
                    {
                        score -= EvalConstants.PassedCandidate[7 - index / 8];
                    }
                }

                pawns &= pawns - 1;
            }

            return(score);
        }