use chess::{BitBoard, Board, BoardBuilder, ChessMove, Color, Rank, Square, ALL_PIECES};
use crate::Winnability;
pub(crate) const LIGHT_SQUARES: BitBoard = BitBoard(0x55AA55AA55AA55AA);
pub(crate) const DARK_SQUARES: BitBoard = BitBoard(0xAA55AA55AA55AA55);
pub(crate) const PROMOTION_RANKS: BitBoard = BitBoard(0xFF000000000000FF);
pub(crate) fn mirror_board(board: &Board) -> Board {
let mut builder = BoardBuilder::new();
for piece in ALL_PIECES.iter() {
let white_pieces = *board.pieces(*piece) & *board.color_combined(Color::White);
let flipped_white = white_pieces.reverse_colors();
for square in flipped_white {
builder.piece(square, *piece, Color::Black);
}
let black_pieces = *board.pieces(*piece) & *board.color_combined(Color::Black);
let flipped_black = black_pieces.reverse_colors();
for square in flipped_black {
builder.piece(square, *piece, Color::White);
}
}
builder.side_to_move(!board.side_to_move());
builder.castle_rights(Color::White, board.castle_rights(Color::Black));
builder.castle_rights(Color::Black, board.castle_rights(Color::White));
if let Some(ep_square) = board.en_passant() {
builder.en_passant(Some(ep_square.get_file()));
}
Board::try_from(builder).expect("Failed to mirror board")
}
pub(crate) fn mirror_moves(winnability: Winnability) -> Winnability {
fn mirror_square(sq: Square) -> Square {
Square::make_square(Rank::from_index(7 - sq.get_rank().to_index()), sq.get_file())
}
fn mirror_move(m: ChessMove) -> ChessMove {
ChessMove::new(
mirror_square(m.get_source()),
mirror_square(m.get_dest()),
m.get_promotion(),
)
}
match winnability {
Winnability::Winnable { helpmate } => {
Winnability::Winnable { helpmate: helpmate.into_iter().map(mirror_move).collect() }
}
other => other,
}
}