private static CastlingRights UpdateCastlingRightsForSide(CastlingRights castlingRights, Board newBoard, Side side) { if ((Castling.KingSideRookFrom(side) & newBoard[side, Piece.Rook]) == 0) { castlingRights = castlingRights.RemoveKingSide(side); } if ((Castling.QueenSideRookFrom(side) & newBoard[side, Piece.Rook]) == 0) { castlingRights = castlingRights.RemoveQueenSide(side); } return(castlingRights); }
internal static void AddCastlingMoves(Position position, List <Move> allMoves) { Side side = position.SideToMove; Board board = position.Board; if (board[side, Piece.King] == 0) { return; } if (Castling.CanCastleKingside(position.CastlingRights, side)) { var kingsideBetween = Castling.KingSideBetween(side); bool spaceAvailable = BitUtils.IsASubsetOfB(kingsideBetween, board.EmptySquares); var kingsideChecks = Castling.KingSideChecks(side); Bitboard enemyAttacks = board.AttacksBy(position.OpposingSide); bool avoidsChecks = (kingsideChecks & enemyAttacks) == 0; if (spaceAvailable && avoidsChecks) { Bitboard king = board[side, Piece.King]; Bitboard castleTarget = king.EastOne().EastOne(); Square from = (Square)king.Serialize()[0]; Square to = (Square)castleTarget.Serialize()[0]; allMoves.Add(new Move(from, to, MoveFlags.KingCastle)); } } if (Castling.CanCastleQueenside(position.CastlingRights, side)) { var queensideBetween = Castling.QueenSideBetween(side); bool spaceAvailable = BitUtils.IsASubsetOfB(queensideBetween, board.EmptySquares); var queensideChecks = Castling.QueenSideChecks(side); Bitboard enemyAttacks = board.AttacksBy(position.OpposingSide); bool avoidsChecks = (queensideChecks & enemyAttacks) == 0; if (spaceAvailable && avoidsChecks) { Bitboard king = board[side, Piece.King]; Bitboard castleTarget = king.WestOne().WestOne(); Square from = (Square)king.Serialize()[0]; Square to = (Square)castleTarget.Serialize()[0]; allMoves.Add(new Move(from, to, MoveFlags.QueenCastle)); } } }
public static void ApplyMoveToBoard(Board board, Move move, out Piece fromPiece) { (Side fromSide, Piece fromPiece_) = board.GetPieceOnSquare(move.From); fromPiece = fromPiece_; Bitboard from = Bitboard.FromSquare(move.From); Bitboard to = Bitboard.FromSquare(move.To); Bitboard fromTo = from | to; if (move.Flags == MoveFlags.EnPassantCapture) { Bitboard capturedPawn = fromSide switch { Side.White => to.SoutOne(), Side.Black => to.NortOne(), _ => throw new IndexOutOfRangeException(nameof(fromSide)) }; board[fromSide.OpposingSide(), Piece.Pawn] ^= capturedPawn; } else if (move.IsCapture) { (Side toSide, Piece toPiece) = board.GetPieceOnSquare(move.To); board[toSide, toPiece] ^= to; } else if (move.Flags == MoveFlags.KingCastle) { board[fromSide, Piece.Rook] ^= Castling.KingSideRookToFrom(fromSide); } else if (move.Flags == MoveFlags.QueenCastle) { board[fromSide, Piece.Rook] ^= Castling.QueenSideRookToFrom(fromSide); } board[fromSide, fromPiece] ^= fromTo; if (move.IsPromotion) { board[fromSide, fromPiece] ^= to; board[fromSide, move.PromotionPiece !.Value] ^= to;