public void CanGenerateBitboardFromNullableSquare(Square?square, ulong expectedBitboard) { // Act var bb = Bitboard.FromSquare(square); // Assert Assert.Equal <Bitboard>(expectedBitboard, bb); }
private static void AddMovesFromAttacks(Bitboard attacks, Square from, Side sideToMove, Board board, List <Move> allMoves) { Bitboard validAttacks = attacks & ~board.FriendlyPieces(sideToMove); int[] targetSquares = validAttacks.Serialize(); for (int t = 0; t < targetSquares.Length; t++) { Square to = (Square)targetSquares[t]; bool isCapture = (Bitboard.FromSquare(to) & board.OpposingPieces(sideToMove)) != 0; if (isCapture) { (_, Piece targetPiece) = board.GetPieceOnSquare(to); allMoves.Add(new Move(from, to, MoveFlags.Capture, targetPiece)); } else { allMoves.Add(new Move(from, to, MoveFlags.QuietMove)); } } }
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;
internal static void AddAllPawnMoves(Position position, List <Move> allMoves) { Board board = position.Board; Side sideToMove = position.SideToMove; Bitboard enPassantTarget = Bitboard.FromSquare(position.EnPassantSquare); Bitboard pawns = board[sideToMove, Piece.Pawn]; // Single pushes Bitboard singlePawnPushTargets = PawnMoves.PawnSinglePushTargets(pawns, board.EmptySquares, sideToMove); Bitboard singlePawnPushSources = sideToMove == Side.White ? singlePawnPushTargets.SoutOne() : singlePawnPushTargets.NortOne(); AddPawnPushes(singlePawnPushTargets, singlePawnPushSources, allMoves, false); // Double pushes Bitboard doublePawnPushTargets = PawnMoves.PawnDoublePushTargets(pawns, board.EmptySquares, sideToMove); Bitboard doublePawnPushSources = sideToMove == Side.White ? doublePawnPushTargets.SoutOne().SoutOne() : doublePawnPushTargets.NortOne().NortOne(); AddPawnPushes(doublePawnPushTargets, doublePawnPushSources, allMoves, true); // Pawn captures int[] pawnSquares = pawns.Serialize(); for (int p = 0; p < pawnSquares.Length; p++) { Square from = (Square)pawnSquares[p]; Bitboard validAttacks; if (sideToMove == Side.White) { validAttacks = PawnMoves.WhitePawnAttacks(from) & (board.BlackPieces | enPassantTarget); } else if (sideToMove == Side.Black) { validAttacks = PawnMoves.BlackPawnAttacks(from) & (board.WhitePieces | enPassantTarget); } else { throw new IndexOutOfRangeException(nameof(sideToMove)); } int[] targetSquares = validAttacks.Serialize(); for (int t = 0; t < targetSquares.Length; t++) { Square to = (Square)targetSquares[t]; if (to == position.EnPassantSquare) { allMoves.Add(new Move(from, to, MoveFlags.EnPassantCapture, Piece.Pawn)); continue; } (_, Piece targetPiece) = board.GetPieceOnSquare(to); if (IsFinalRank(to)) { var promotions = new[] { new Move(from, to, MoveFlags.Capture | MoveFlags.KnightPromotion, targetPiece), new Move(from, to, MoveFlags.Capture | MoveFlags.BishopPromotion, targetPiece), new Move(from, to, MoveFlags.Capture | MoveFlags.RookPromotion, targetPiece), new Move(from, to, MoveFlags.Capture | MoveFlags.QueenPromotion, targetPiece), }; allMoves.AddRange(promotions); } else { var flags = to == position.EnPassantSquare ? MoveFlags.EnPassantCapture : MoveFlags.Capture; allMoves.Add(new Move(from, to, flags, targetPiece)); } } } }