Example #1
0
        public static int GetSeeCaptureScore(ChessBoard cb, int move)
        {
            if (EngineConstants.Assert)
            {
                if (MoveUtil.GetAttackedPieceIndex(move) == 0)
                {
                    Assert.IsTrue(MoveUtil.GetMoveType(move) != 0);
                }
            }

            var index       = MoveUtil.GetToIndex(move);
            var allPieces   = cb.AllPieces & ~Util.PowerLookup[MoveUtil.GetFromIndex(move)];
            var slidingMask = MagicUtil.GetQueenMovesEmptyBoard(index) & allPieces;

            // add score when promotion
            if (MoveUtil.IsPromotion(move))
            {
                return(EvalConstants.PromotionScore[MoveUtil.GetMoveType(move)] +
                       EvalConstants.Material[MoveUtil.GetAttackedPieceIndex(move)]
                       - GetSeeScore(cb, cb.ColorToMoveInverse, index, MoveUtil.GetMoveType(move), allPieces,
                                     slidingMask));
            }

            return(EvalConstants.Material[MoveUtil.GetAttackedPieceIndex(move)]
                   - GetSeeScore(cb, cb.ColorToMoveInverse, index, MoveUtil.GetSourcePieceIndex(move), allPieces,
                                 slidingMask));
        }
Example #2
0
 public static bool IsInCheck(int kingIndex, int colorToMove, long[] enemyPieces, long allPieces)
 {
     // put 'super-piece' in kings position
     return(((enemyPieces[Knight] & StaticMoves.KnightMoves[kingIndex])
             | ((enemyPieces[Rook] | enemyPieces[Queen]) & MagicUtil.GetRookMoves(kingIndex, allPieces))
             | ((enemyPieces[Bishop] | enemyPieces[Queen]) & MagicUtil.GetBishopMoves(kingIndex, allPieces))
             | (enemyPieces[Pawn] & StaticMoves.PawnAttacks[colorToMove][kingIndex])
             ) != 0);
 }
Example #3
0
        private static int Checks(ChessBoard cb, int kingColor)
        {
            var kingIndex       = cb.KingIndex[kingColor];
            var enemyColor      = 1 - kingColor;
            var notDefended     = ~cb.Attacks[kingColor][All];
            var unOccupied      = ~cb.Pieces[enemyColor][All];
            var unsafeKingMoves = StaticMoves.KingMoves[kingIndex] & cb.DoubleAttacks[enemyColor] &
                                  ~cb.DoubleAttacks[kingColor];

            var counter = 0;

            if (cb.Pieces[enemyColor][Knight] != 0)
            {
                counter += CheckMinor(notDefended,
                                      StaticMoves.KnightMoves[kingIndex] & unOccupied & cb.Attacks[enemyColor][Knight]);
            }

            long moves;
            long queenMoves = 0;

            if ((cb.Pieces[enemyColor][Queen] | cb.Pieces[enemyColor][Bishop]) != 0)
            {
                moves      = MagicUtil.GetBishopMoves(kingIndex, cb.AllPieces ^ cb.Pieces[kingColor][Queen]) & unOccupied;
                queenMoves = moves;
                counter   += CheckMinor(notDefended, moves & cb.Attacks[enemyColor][Bishop]);
            }

            if ((cb.Pieces[enemyColor][Queen] | cb.Pieces[enemyColor][Rook]) != 0)
            {
                moves       = MagicUtil.GetRookMoves(kingIndex, cb.AllPieces ^ cb.Pieces[kingColor][Queen]) & unOccupied;
                queenMoves |= moves;
                counter    += CheckRook(cb, kingColor, moves & cb.Attacks[enemyColor][Rook],
                                        unsafeKingMoves | notDefended);
            }

            queenMoves &= cb.Attacks[enemyColor][Queen];
            if (queenMoves == 0)
            {
                return(counter);
            }
            // safe check queen
            if ((queenMoves & notDefended) != 0)
            {
                counter += EvalConstants.KsCheckQueen[BitOperations.PopCount((ulong)cb.Pieces[kingColor][All])];
            }

            // safe check queen touch
            if ((queenMoves & unsafeKingMoves) != 0)
            {
                counter += EvalConstants.KsOther[0];
            }

            return(counter);
        }
Example #4
0
        public void SetCheckingPinnedAndDiscoPieces()
        {
            PinnedPieces     = 0;
            DiscoveredPieces = 0;
            CheckingPieces   = (Pieces[ColorToMoveInverse][Knight] & StaticMoves.KnightMoves[KingIndex[ColorToMove]])
                               | (Pieces[ColorToMoveInverse][Pawn] &
                                  StaticMoves.PawnAttacks[ColorToMove][KingIndex[ColorToMove]]);

            for (var kingColor = White; kingColor <= Black; kingColor++)
            {
                var enemyColor = 1 - kingColor;

                if (!MaterialUtil.HasSlidingPieces(MaterialKey, enemyColor))
                {
                    continue;
                }

                var enemyPiece = ((Pieces[enemyColor][Bishop] | Pieces[enemyColor][Queen]) &
                                  MagicUtil.GetBishopMovesEmptyBoard(KingIndex[kingColor]))
                                 | ((Pieces[enemyColor][Rook] | Pieces[enemyColor][Queen]) &
                                    MagicUtil.GetRookMovesEmptyBoard(KingIndex[kingColor]));
                while (enemyPiece != 0)
                {
                    var checkedPiece = InBetween[KingIndex[kingColor]][BitOperations.TrailingZeroCount(enemyPiece)] &
                                       AllPieces;
                    if (checkedPiece == 0)
                    {
                        CheckingPieces |= enemyPiece & -enemyPiece;
                    }
                    else if (BitOperations.PopCount((ulong)checkedPiece) == 1)
                    {
                        PinnedPieces     |= checkedPiece & Pieces[kingColor][All];
                        DiscoveredPieces |= checkedPiece & Pieces[enemyColor][All];
                    }

                    enemyPiece &= enemyPiece - 1;
                }
            }
        }
Example #5
0
        private static int GetSmallestAttackSeeMove(long[] pieces, int colorToMove, int toIndex,
                                                    long allPieces, long slidingMask)
        {
            // TODO stop when bad-capture

            // put 'super-piece' in see position

            // pawn non-promotion attacks
            var attackMove = StaticMoves.PawnAttacks[1 - colorToMove][toIndex] & pieces[Pawn] & allPieces;

            if (attackMove != 0)
            {
                return(BitOperations.TrailingZeroCount(attackMove));
            }

            // knight attacks
            attackMove = pieces[Knight] & StaticMoves.KnightMoves[toIndex] & allPieces;
            if (attackMove != 0)
            {
                return(BitOperations.TrailingZeroCount(attackMove));
            }

            // bishop attacks
            if ((pieces[Bishop] & slidingMask) != 0)
            {
                attackMove = pieces[Bishop] & MagicUtil.GetBishopMoves(toIndex, allPieces) & allPieces;
                if (attackMove != 0)
                {
                    return(BitOperations.TrailingZeroCount(attackMove));
                }
            }

            // rook attacks
            if ((pieces[Rook] & slidingMask) != 0)
            {
                attackMove = pieces[Rook] & MagicUtil.GetRookMoves(toIndex, allPieces) & allPieces;
                if (attackMove != 0)
                {
                    return(BitOperations.TrailingZeroCount(attackMove));
                }
            }

            // queen attacks
            if ((pieces[Queen] & slidingMask) != 0)
            {
                attackMove = pieces[Queen] & MagicUtil.GetQueenMoves(toIndex, allPieces) & allPieces;
                if (attackMove != 0)
                {
                    return(BitOperations.TrailingZeroCount(attackMove));
                }
            }

            // king attacks
            attackMove = pieces[King] & StaticMoves.KingMoves[toIndex];
            if (attackMove != 0)
            {
                return(BitOperations.TrailingZeroCount(attackMove));
            }

            return(-1);
        }
Example #6
0
        public static int CalculateMobilityScoresAndSetAttacks(ChessBoard cb)
        {
            cb.ClearEvalAttacks();

            for (var color = White; color <= Black; color++)
            {
                var kingArea = KingArea[cb.KingIndex[1 - color]];
                var piece    = cb.Pieces[color][Pawn] & ~cb.PinnedPieces;
                while (piece != 0)
                {
                    cb.UpdatePawnAttacks(StaticMoves.PawnAttacks[color][BitOperations.TrailingZeroCount(piece)], color);
                    piece &= piece - 1;
                }

                cb.UpdatePawnAttacks(color, kingArea);

                piece = cb.Pieces[color][Pawn] & cb.PinnedPieces;
                while (piece != 0)
                {
                    cb.UpdateAttacks(StaticMoves.PawnAttacks[color][BitOperations.TrailingZeroCount(piece)]
                                     & PinnedMovement[BitOperations.TrailingZeroCount(piece)][cb.KingIndex[color]],
                                     Pawn,
                                     color, kingArea);
                    piece &= piece - 1;
                }
            }

            var  score = 0;
            long moves;

            for (var color = White; color <= Black; color++)
            {
                var tempScore = 0;

                var kingArea  = KingArea[cb.KingIndex[1 - color]];
                var safeMoves = ~cb.Pieces[color][All] & ~cb.Attacks[1 - color][Pawn];

                // knights
                var piece = cb.Pieces[color][Knight] & ~cb.PinnedPieces;
                while (piece != 0)
                {
                    moves = StaticMoves.KnightMoves[BitOperations.TrailingZeroCount(piece)];
                    cb.UpdateAttacks(moves, Knight, color, kingArea);
                    tempScore += EvalConstants.MobilityKnight[BitOperations.PopCount((ulong)(moves & safeMoves))];
                    piece     &= piece - 1;
                }

                // bishops
                piece = cb.Pieces[color][Bishop];
                while (piece != 0)
                {
                    moves = MagicUtil.GetBishopMoves(BitOperations.TrailingZeroCount(piece),
                                                     cb.AllPieces ^ cb.Pieces[color][Queen]);
                    cb.UpdateAttacks(moves, Bishop, color, kingArea);
                    tempScore += EvalConstants.MobilityBishop[BitOperations.PopCount((ulong)(moves & safeMoves))];
                    piece     &= piece - 1;
                }

                // rooks
                piece = cb.Pieces[color][Rook];
                while (piece != 0)
                {
                    moves = MagicUtil.GetRookMoves(BitOperations.TrailingZeroCount(piece),
                                                   cb.AllPieces ^ cb.Pieces[color][Rook] ^ cb.Pieces[color][Queen]);
                    cb.UpdateAttacks(moves, Rook, color, kingArea);
                    tempScore += EvalConstants.MobilityRook[BitOperations.PopCount((ulong)(moves & safeMoves))];
                    piece     &= piece - 1;
                }

                // queens
                piece = cb.Pieces[color][Queen];
                while (piece != 0)
                {
                    moves = MagicUtil.GetQueenMoves(BitOperations.TrailingZeroCount(piece), cb.AllPieces);
                    cb.UpdateAttacks(moves, Queen, color, kingArea);
                    tempScore += EvalConstants.MobilityQueen[BitOperations.PopCount((ulong)(moves & safeMoves))];
                    piece     &= piece - 1;
                }

                score += tempScore * ColorFactor[color];
            }

            // TODO king-attacks with or without enemy attacks?
            // WHITE king
            moves = StaticMoves.KingMoves[cb.KingIndex[White]] & ~StaticMoves.KingMoves[cb.KingIndex[Black]];
            cb.Attacks[White][King]  = moves;
            cb.DoubleAttacks[White] |= cb.Attacks[White][All] & moves;
            cb.Attacks[White][All]  |= moves;
            score += EvalConstants.MobilityKing[
                BitOperations.PopCount((ulong)(moves & ~cb.Pieces[White][All] & ~cb.Attacks[Black][All]))];

            // BLACK king
            moves = StaticMoves.KingMoves[cb.KingIndex[Black]] & ~StaticMoves.KingMoves[cb.KingIndex[White]];
            cb.Attacks[Black][King]  = moves;
            cb.DoubleAttacks[Black] |= cb.Attacks[Black][All] & moves;
            cb.Attacks[Black][All]  |= moves;
            score -= EvalConstants.MobilityKing[
                BitOperations.PopCount((ulong)(moves & ~cb.Pieces[Black][All] & ~cb.Attacks[White][All]))];

            return(score);
        }