Example #1
0
        private ulong HorizontalVerticalXray(ulong allPieces, ulong ownPieces, byte position)
        {
            var attacks = _slideMoveGenerator.HorizontalVerticalSlide(allPieces, position);

            ownPieces &= attacks;
            var xrayAttacks = attacks ^ _slideMoveGenerator.HorizontalVerticalSlide(allPieces ^ ownPieces, position);

            return(xrayAttacks);
        }
        private void GetPotentialRookMoves(Board board, Bitboard allowedFrom, Bitboard allowedTo, Move[] moves, ref int moveCount)
        {
            var piece         = (Piece)(ChessPiece.Rook | board.ColorToMove);
            var piecesBitmask = board.BitBoard[piece] & allowedFrom;
            var ownPieces     = board.WhiteToMove ? board.WhitePieces : board.BlackPieces;

            while (piecesBitmask != 0)
            {
                var      position = piecesBitmask.BitScanForward();
                Bitboard slide    = _slideMoveGenerator.HorizontalVerticalSlide(board.AllPieces, position);
                slide &= ~ownPieces;
                slide &= allowedTo;
                BitmaskToMoves(board, slide, position, piece, moves, ref moveCount);
                piecesBitmask &= piecesBitmask - 1;
            }
        }
        public void EvalRook(Board b, EvaluationScores v, Position sq, Piece side, ulong pinned)
        {
            int att = 0;
            int mob = 0;

            var sqCol = sq & 7;
            var sqRow = sq >> 3;

            /**************************************************************************
            *  Bonus for rook on the seventh rank. It is applied when there are pawns *
            *  to attack along that rank or if enemy king is cut off on 8th rank      *
            *  /*************************************************************************/

            //if
            //(
            //    sqRow == EvaluationData.seventh[side]
            //    && (eb.pawns_on_rank[side ^ 1, EvaluationData.seventh[side]] > 0 || (b.KingPositions[side ^ 1]) == EvaluationData.eighth[side])
            //)

            var seventh = EvaluationData.seventh[side];
            var eighth  = EvaluationData.eighth[side];

            if
            (
                sqRow == seventh &&
                (
                    (b.BitBoard[ChessPiece.Pawn + side ^ 1] & BitboardConstants.Ranks[seventh]) != 0 ||
                    (b.BitBoard[ChessPiece.King + side ^ 1] & BitboardConstants.Ranks[eighth]) != 0
                )
            )
            {
                v.mgMob[side] += 20;
                v.egMob[side] += 30;
            }

            /**************************************************************************
            *  Bonus for open and half-open files is merged with mobility score.      *
            *  Bonus for open files targetting enemy king is added to attWeight[]     *
            *  /*************************************************************************/
            var file           = BitboardConstants.Files[sqCol];
            var ownPawnsOnFile = b.BitBoard[ChessPiece.Pawn + side] & file;

            if (ownPawnsOnFile == 0)
            {
                var opponentPawnsOnFile = b.BitBoard[ChessPiece.Pawn + side ^ 1] & file;
                if (opponentPawnsOnFile == 0) // fully open file
                {
                    v.mgMob[side] += EvaluationData.ROOK_OPEN;
                    v.egMob[side] += EvaluationData.ROOK_OPEN;
                    if (Math.Abs(sqCol - (b.KingPositions[side ^ 1] & 7)) < 2)
                    {
                        v.attWeight[side] += 1;
                    }
                }
                else // half open file
                {
                    v.mgMob[side] += EvaluationData.ROOK_HALF;
                    v.egMob[side] += EvaluationData.ROOK_HALF;
                    if (Math.Abs(sqCol - (b.KingPositions[side ^ 1] & 7)) < 2)
                    {
                        v.attWeight[side] += 2;
                    }
                }
            }

            /**************************************************************************
            *  Collect data about mobility and king attacks                           *
            **************************************************************************/

            var slide = _slideGenerator.HorizontalVerticalSlide(b.AllPieces, sq);

            var opponent        = side == ChessPiece.White ? b.BlackPieces : b.WhitePieces;
            var emptyOrOpponent = (b.EmptySquares | opponent) & slide;

            var bitboard = 1UL << sq;

            if ((bitboard & pinned) == 0)
            {
                mob += emptyOrOpponent.PopCount();
            }

            var emptyOrOpponentNearKing = emptyOrOpponent & BitboardConstants.KingExtendedJumps[side ^ 1][b.KingPositions[side ^ 1]];

            att += emptyOrOpponentNearKing.PopCount();

            v.mgMob[side] += 2 * (mob - 7);
            v.egMob[side] += 4 * (mob - 7);

            if (att > 0)
            {
                v.attCnt[side]++;
                v.attWeight[side] += 3 * att;
            }

            int tropism = getTropism(sq, b.KingPositions[side ^ 1]);

            v.mgTropism[side] += 2 * tropism;
            v.egTropism[side] += 1 * tropism;
        }
Example #4
0
        private MagicBitboardGenerationEntry InitEntry(Bitboard blockerMask, bool bishop, int pos)
        {
            var entry = new MagicBitboardGenerationEntry();

            entry.Position    = pos;
            entry.BlockerMask = blockerMask;
            entry.Bishop      = bishop;

            var maskCopy = blockerMask;
            var bits     = new List <int>();

            while (maskCopy != 0)
            {
                var blockerPosition = maskCopy.BitScanForward();
                bits.Add(blockerPosition);
                maskCopy &= maskCopy - 1;
            }

            var permutations = 1 << bits.Count;

            entry.BitCount    = (byte)bits.Count;
            entry.Occupancies = new Bitboard[permutations];
            entry.Moveboards  = new Bitboard[permutations];

            for (var i = 0; i < permutations; i++)
            {
                Bitboard occMask = 0;
                for (var j = 0; j < bits.Count; j++)
                {
                    var shouldSet = (i & (1 << j)) > 0;
                    if (shouldSet)
                    {
                        var bit = bits[j];
                        occMask |= 1UL << bit;
                    }
                }

                entry.Occupancies[i] = occMask;
                var moveboard = bishop ? _otherSlideGenerator.DiagonalAntidiagonalSlide(occMask, pos) : _otherSlideGenerator.HorizontalVerticalSlide(occMask, pos);
                entry.Moveboards[i] = moveboard;
            }

            entry.MagicNumber = FindMagicNumber(entry);

            return(entry);
        }
Example #5
0
        public bool IsKingSafeAfterMove(Board board, Move move)
        {
            var allPieces    = board.AllPieces;
            var fromBitboard = 1UL << move.From;
            var toBitboard   = 1UL << move.To;

            allPieces &= ~fromBitboard;
            allPieces |= toBitboard;

            var takesBitboard = toBitboard;

            if (move.EnPassant)
            {
                var enPassantedBitboard = board.WhiteToMove ? toBitboard >> 8 : toBitboard << 8;
                allPieces     &= ~enPassantedBitboard;
                takesBitboard |= enPassantedBitboard;
            }

            var  kingMove  = move.Piece == ChessPiece.WhiteKing || move.Piece == ChessPiece.BlackKing;
            Byte myKingPos = kingMove ? move.To : board.KingPositions[board.ColorToMove];

            //Position myKingPos = board.KingPositions[board.ColorToMove];

            var invTakes = ~takesBitboard;

            UInt64 pawns;
            UInt64 knights;
            UInt64 bishops;
            UInt64 rooks;
            UInt64 queens;
            UInt64 kings;

            if (board.WhiteToMove)
            {
                pawns   = board.BitBoard[ChessPiece.BlackPawn] & invTakes;
                knights = board.BitBoard[ChessPiece.BlackKnight] & invTakes;
                bishops = board.BitBoard[ChessPiece.BlackBishop] & invTakes;
                rooks   = board.BitBoard[ChessPiece.BlackRook] & invTakes;
                queens  = board.BitBoard[ChessPiece.BlackQueen] & invTakes;
                kings   = board.BitBoard[ChessPiece.BlackKing] & invTakes;
            }
            else
            {
                pawns   = board.BitBoard[ChessPiece.WhitePawn] & invTakes;
                knights = board.BitBoard[ChessPiece.WhiteKnight] & invTakes;
                bishops = board.BitBoard[ChessPiece.WhiteBishop] & invTakes;
                rooks   = board.BitBoard[ChessPiece.WhiteRook] & invTakes;
                queens  = board.BitBoard[ChessPiece.WhiteQueen] & invTakes;
                kings   = board.BitBoard[ChessPiece.WhiteKing] & invTakes;
            }

            var knightAttack = BitboardConstants.KnightJumps[myKingPos];

            if ((knightAttack & knights) != 0)
            {
                return(false);
            }

            var kingAttack = BitboardConstants.KingJumps[myKingPos];

            if ((kingAttack & kings) != 0)
            {
                return(false);
            }

            var pawnAttack = BitboardConstants.PawnJumps[move.ColorToMove, myKingPos]; //AttacksService.GetAttackedByPawns(myKings, board.WhiteToMove);

            if ((pawnAttack & pawns) != 0)
            {
                return(false);
            }

            var diagonalAttack = _slideMoveGenerator.DiagonalAntidiagonalSlide(allPieces, myKingPos);

            if ((diagonalAttack & (bishops | queens)) != 0)
            {
                return(false);
            }

            var verticalAttack = _slideMoveGenerator.HorizontalVerticalSlide(allPieces, myKingPos);

            if ((verticalAttack & (rooks | queens)) != 0)
            {
                return(false);
            }

            return(true);
        }