Example #1
0
        public static int CalculateSpace(ChessBoard cb)
        {
            if (!MaterialUtil.HasPawns(cb.MaterialKey))
            {
                return(0);
            }

            var score = 0;

            score += EvalConstants.OtherScores[EvalConstants.IxSpace]
                     * BitOperations.PopCount((ulong)(Util.RightTripleShift(cb.Pieces[White][Pawn], 8) &
                                                      (cb.Pieces[White][Knight] | cb.Pieces[White][Bishop]) &
                                                      Bitboard.Rank234));
            score -= EvalConstants.OtherScores[EvalConstants.IxSpace]
                     * BitOperations.PopCount((ulong)((cb.Pieces[Black][Pawn] << 8) &
                                                      (cb.Pieces[Black][Knight] | cb.Pieces[Black][Bishop]) &
                                                      Bitboard.Rank567));

            // idea taken from Laser
            var space = Util.RightTripleShift(cb.Pieces[White][Pawn], 8);

            space |= Util.RightTripleShift(space, 8) | Util.RightTripleShift(space, 16);
            score += EvalConstants.Space[BitOperations.PopCount((ulong)cb.Pieces[White][All])]
                     * BitOperations.PopCount((ulong)(space & ~cb.Pieces[White][Pawn] & ~cb.Attacks[Black][Pawn] &
                                                      Bitboard.FileCdef));
            space  = cb.Pieces[Black][Pawn] << 8;
            space |= (space << 8) | (space << 16);
            score -= EvalConstants.Space[BitOperations.PopCount((ulong)cb.Pieces[Black][All])]
                     * BitOperations.PopCount((ulong)(space & ~cb.Pieces[Black][Pawn] & ~cb.Attacks[White][Pawn] &
                                                      Bitboard.FileCdef));

            return(score);
        }
Example #2
0
        public static int CalculatePawnShieldBonus(ChessBoard cb)
        {
            if (!MaterialUtil.HasPawns(cb.MaterialKey))
            {
                return(0);
            }

            int file;

            var whiteScore = 0;
            var piece      = cb.Pieces[White][Pawn] & KingArea[cb.KingIndex[White]] & ~cb.Attacks[Black][Pawn];

            while (piece != 0)
            {
                file        = BitOperations.TrailingZeroCount(piece) & 7;
                whiteScore +=
                    EvalConstants.ShieldBonus[Math.Min(7 - file, file)][
                        Util.RightTripleShift(BitOperations.TrailingZeroCount(piece), 3)];
                piece &= ~Bitboard.Files[file];
            }

            if (cb.Pieces[Black][Queen] == 0)
            {
                whiteScore /= 2;
            }

            var blackScore = 0;

            piece = cb.Pieces[Black][Pawn] & KingArea[cb.KingIndex[Black]] & ~cb.Attacks[White][Pawn];
            while (piece != 0)
            {
                file        = (63 - BitOperations.LeadingZeroCount((ulong)piece)) & 7;
                blackScore +=
                    EvalConstants.ShieldBonus[Math.Min(7 - file, file)]
                    [7 - (63 - BitOperations.LeadingZeroCount((ulong)piece)) / 8];
                piece &= ~Bitboard.Files[file];
            }

            if (cb.Pieces[White][Queen] == 0)
            {
                blackScore /= 2;
            }

            return(whiteScore - blackScore);
        }
Example #3
0
        public static int CalculateThreats(ChessBoard cb)
        {
            var score             = 0;
            var whites            = cb.Pieces[White][All];
            var whitePawns        = cb.Pieces[White][Pawn];
            var blacks            = cb.Pieces[Black][All];
            var blackPawns        = cb.Pieces[Black][Pawn];
            var whiteAttacks      = cb.Attacks[White][All];
            var whitePawnAttacks  = cb.Attacks[White][Pawn];
            var whiteMinorAttacks = cb.Attacks[White][Knight] | cb.Attacks[White][Bishop];
            var blackAttacks      = cb.Attacks[Black][All];
            var blackPawnAttacks  = cb.Attacks[Black][Pawn];
            var blackMinorAttacks = cb.Attacks[Black][Knight] | cb.Attacks[Black][Bishop];

            // double attacked pieces
            var piece = cb.DoubleAttacks[White] & blacks;

            while (piece != 0)
            {
                score += EvalConstants.DoubleAttacked[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                piece &= piece - 1;
            }

            piece = cb.DoubleAttacks[Black] & whites;
            while (piece != 0)
            {
                score -= EvalConstants.DoubleAttacked[cb.PieceIndexes[BitOperations.TrailingZeroCount(piece)]];
                piece &= piece - 1;
            }

            if (MaterialUtil.HasPawns(cb.MaterialKey))
            {
                // unused outposts
                score += BitOperations.PopCount((ulong)(cb.PassedPawnsAndOutposts & cb.EmptySpaces &
                                                        whiteMinorAttacks & whitePawnAttacks))
                         * EvalConstants.Threats[EvalConstants.IxUnusedOutpost];
                score -= BitOperations.PopCount((ulong)(cb.PassedPawnsAndOutposts & cb.EmptySpaces &
                                                        blackMinorAttacks & blackPawnAttacks))
                         * EvalConstants.Threats[EvalConstants.IxUnusedOutpost];

                // pawn push threat
                piece  = (whitePawns << 8) & cb.EmptySpaces & ~blackAttacks;
                score += BitOperations.PopCount((ulong)(Bitboard.GetWhitePawnAttacks(piece) & blacks)) *
                         EvalConstants.Threats[EvalConstants.IxPawnPushThreat];
                piece  = Util.RightTripleShift(blackPawns, 8) & cb.EmptySpaces & ~whiteAttacks;
                score -= BitOperations.PopCount((ulong)(Bitboard.GetBlackPawnAttacks(piece) & whites)) *
                         EvalConstants.Threats[EvalConstants.IxPawnPushThreat];

                // piece attacked by pawn
                score += BitOperations.PopCount((ulong)(whitePawnAttacks & blacks & ~blackPawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacks];
                score -= BitOperations.PopCount((ulong)(blackPawnAttacks & whites & ~whitePawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacks];

                // multiple pawn attacks possible
                if (BitOperations.PopCount((ulong)(whitePawnAttacks & blacks)) > 1)
                {
                    score += EvalConstants.Threats[EvalConstants.IxMultiplePawnAttacks];
                }

                if (BitOperations.PopCount((ulong)(blackPawnAttacks & whites)) > 1)
                {
                    score -= EvalConstants.Threats[EvalConstants.IxMultiplePawnAttacks];
                }

                // pawn attacked
                score += BitOperations.PopCount((ulong)(whiteAttacks & blackPawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacked];
                score -= BitOperations.PopCount((ulong)(blackAttacks & whitePawns)) *
                         EvalConstants.Threats[EvalConstants.IxPawnAttacked];
            }

            // minors attacked and not defended by a pawn
            score += BitOperations.PopCount((ulong)(whiteAttacks &
                                                    (cb.Pieces[Black][Knight] |
                                                     (cb.Pieces[Black][Bishop] & ~blackAttacks))))
                     * EvalConstants.Threats[EvalConstants.IxMajorAttacked];
            score -= BitOperations.PopCount((ulong)(blackAttacks &
                                                    (cb.Pieces[White][Knight] |
                                                     (cb.Pieces[White][Bishop] & ~whiteAttacks))))
                     * EvalConstants.Threats[EvalConstants.IxMajorAttacked];

            if (cb.Pieces[Black][Queen] != 0)
            {
                // queen attacked by rook
                score += BitOperations.PopCount((ulong)(cb.Attacks[White][Rook] & cb.Pieces[Black][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttacked];
                // queen attacked by minors
                score += BitOperations.PopCount((ulong)(whiteMinorAttacks & cb.Pieces[Black][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttackedMinor];
            }

            if (cb.Pieces[White][Queen] != 0)
            {
                // queen attacked by rook
                score -= BitOperations.PopCount((ulong)(cb.Attacks[Black][Rook] & cb.Pieces[White][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttacked];
                // queen attacked by minors
                score -= BitOperations.PopCount((ulong)(blackMinorAttacks & cb.Pieces[White][Queen])) *
                         EvalConstants.Threats[EvalConstants.IxQueenAttackedMinor];
            }

            // rook attacked by minors
            score += BitOperations.PopCount((ulong)(whiteMinorAttacks & cb.Pieces[Black][Rook])) *
                     EvalConstants.Threats[EvalConstants.IxRookAttacked];
            score -= BitOperations.PopCount((ulong)(blackMinorAttacks & cb.Pieces[White][Rook])) *
                     EvalConstants.Threats[EvalConstants.IxRookAttacked];

            return(score);
        }