Exemple #1
0
        private void AddPawnMoves(IList <Move> moves, bool onlyCaptures)
        {
            var pawnDirection = board.Us == Piece.WHITE ? Directions[N] : Directions[S];
            var promotionRank = board.Us == Piece.WHITE ? 7 : 0;

            //one square moves
            var ourPawnsBitboard = board.Us == Piece.WHITE ? board.WhitePawnBitboard : board.BlackPawnBitboard;

            var pinnedPawns = pinBitmask & ourPawnsBitboard;

            if (!onlyCaptures)
            {
                var pseudoLegalSinglePawnMoveTargets = board.Us == Piece.WHITE ? BitboardUtilities.ShiftUp(ourPawnsBitboard) : BitboardUtilities.ShiftDown(ourPawnsBitboard);
                pseudoLegalSinglePawnMoveTargets &= freeSquares;
                var legalSinglePawnMoveTarget = pseudoLegalSinglePawnMoveTargets & rayCheckBitmask;

                while (legalSinglePawnMoveTarget != 0)
                {
                    var targetSquare = BitOperations.TrailingZeroCount(legalSinglePawnMoveTarget);
                    var startSquare  = targetSquare - pawnDirection;
                    legalSinglePawnMoveTarget ^= 1ul << targetSquare;
                    if ((pinnedPawns & (1ul << startSquare)) != 0 && !IsMovingAlongRay(pawnDirection, startSquare, ourKingSquare))
                    {
                        continue;
                    }
                    if (targetSquare / 8 == promotionRank)
                    {
                        moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.QUEEN));
                        moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.ROOK));
                        moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.BISHOP));
                        moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.KNIGHT));
                    }
                    else
                    {
                        moves.Add(new Move(startSquare, targetSquare, board));
                    }
                }

                var doublePawnMoveTarget = board.Us == Piece.WHITE ? BitboardUtilities.ShiftUp(pseudoLegalSinglePawnMoveTargets) : BitboardUtilities.ShiftDown(pseudoLegalSinglePawnMoveTargets);
                doublePawnMoveTarget &= RankBitboards[board.Us == Piece.WHITE ? 3 : 4] & freeSquares & rayCheckBitmask;

                while (doublePawnMoveTarget != 0)
                {
                    var targetSquare = BitOperations.TrailingZeroCount(doublePawnMoveTarget);
                    var startSquare  = targetSquare - 2 * pawnDirection;

                    doublePawnMoveTarget ^= 1ul << targetSquare;

                    if ((pinnedPawns & (1ul << startSquare)) != 0)
                    {
                        if (!IsMovingAlongRay(pawnDirection, startSquare, ourKingSquare))
                        {
                            continue;
                        }
                    }
                    moves.Add(new Move(startSquare, targetSquare, board).DoublePawnMove());
                }
            }

            //Captures
            var upWest = Directions[board.Us == Piece.WHITE ? NW : SW];
            var upEast = Directions[board.Us == Piece.WHITE ? NE : SE];
            var enemyPiecesAndEnPassent = board.EnPassentSquare >= 0 ? enemyPieces | (1ul << board.EnPassentSquare) : enemyPieces;
            var captureUpWestTargets    = board.Us == Piece.WHITE ? BitboardUtilities.ShiftUpLeft(ourPawnsBitboard) : BitboardUtilities.ShiftDownLeft(ourPawnsBitboard);

            captureUpWestTargets &= enemyPiecesAndEnPassent & rayCheckBitmask;
            var captureUpEastTargets = board.Us == Piece.WHITE ? BitboardUtilities.ShiftUpRight(ourPawnsBitboard) : BitboardUtilities.ShiftDownRight(ourPawnsBitboard);

            captureUpEastTargets &= enemyPiecesAndEnPassent & rayCheckBitmask;

            while (captureUpWestTargets != 0)
            {
                var targetSquare = BitOperations.TrailingZeroCount(captureUpWestTargets);
                var startSquare  = targetSquare - upWest;
                captureUpWestTargets ^= 1ul << targetSquare;
                if ((pinnedPawns & (1ul << startSquare)) != 0 && !IsMovingAlongRay(upWest, startSquare, ourKingSquare))
                {
                    continue;
                }
                if (targetSquare / 8 == promotionRank)
                {
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.QUEEN));
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.ROOK));
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.BISHOP));
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.KNIGHT));
                }
                else
                {
                    var move = new Move(startSquare, targetSquare, board);
                    if (targetSquare == board.EnPassentSquare)
                    {
                        move.EnPassent();
                    }
                    moves.Add(move);
                }
            }

            while (captureUpEastTargets != 0)
            {
                var targetSquare = BitOperations.TrailingZeroCount(captureUpEastTargets);
                var startSquare  = targetSquare - upEast;
                captureUpEastTargets ^= 1ul << targetSquare;
                if ((pinnedPawns & (1ul << startSquare)) != 0 && !IsMovingAlongRay(upEast, startSquare, ourKingSquare))
                {
                    continue;
                }
                if (targetSquare / 8 == promotionRank)
                {
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.QUEEN));
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.ROOK));
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.BISHOP));
                    moves.Add(new Move(startSquare, targetSquare, board).PromoteTo(Piece.KNIGHT));
                }
                else
                {
                    var move = new Move(startSquare, targetSquare, board);
                    if (targetSquare == board.EnPassentSquare)
                    {
                        move.EnPassent();
                    }
                    moves.Add(move);
                }
            }
        }