use crate::board::PieceMapping;
pub struct CastlingLogic;
impl CastlingLogic {
pub fn can_white_kingside(mapping: &PieceMapping, occupied: u64) -> bool {
mapping.piece_square[15] == Some(4) && mapping.piece_square[9] == Some(7) && (occupied & ((1u64 << 5) | (1u64 << 6))) == 0 }
pub fn do_white_kingside(mapping: &mut PieceMapping, occupied: &mut u64) {
mapping.square_piece[4] = None;
mapping.square_piece[6] = Some(15);
mapping.piece_square[15] = Some(6);
*occupied &= !(1u64 << 4);
*occupied |= 1u64 << 6;
mapping.square_piece[7] = None;
mapping.square_piece[5] = Some(9);
mapping.piece_square[9] = Some(5);
*occupied &= !(1u64 << 7);
*occupied |= 1u64 << 5;
}
pub fn can_white_queenside(mapping: &PieceMapping, occupied: u64) -> bool {
mapping.piece_square[15] == Some(4) && mapping.piece_square[8] == Some(0) && (occupied & ((1u64 << 1) | (1u64 << 2) | (1u64 << 3))) == 0 }
pub fn do_white_queenside(mapping: &mut PieceMapping, occupied: &mut u64) {
mapping.square_piece[4] = None;
mapping.square_piece[2] = Some(15);
mapping.piece_square[15] = Some(2);
*occupied &= !(1u64 << 4);
*occupied |= 1u64 << 2;
mapping.square_piece[0] = None;
mapping.square_piece[3] = Some(8);
mapping.piece_square[8] = Some(3);
*occupied &= !(1u64 << 0);
*occupied |= 1u64 << 3;
}
pub fn can_black_kingside(mapping: &PieceMapping, occupied: u64) -> bool {
mapping.piece_square[31] == Some(60) && mapping.piece_square[25] == Some(63) && (occupied & ((1u64 << 61) | (1u64 << 62))) == 0 }
pub fn do_black_kingside(mapping: &mut PieceMapping, occupied: &mut u64) {
mapping.square_piece[60] = None;
mapping.square_piece[62] = Some(31);
mapping.piece_square[31] = Some(62);
*occupied &= !(1u64 << 60);
*occupied |= 1u64 << 62;
mapping.square_piece[63] = None;
mapping.square_piece[61] = Some(25);
mapping.piece_square[25] = Some(61);
*occupied &= !(1u64 << 63);
*occupied |= 1u64 << 61;
}
pub fn can_black_queenside(mapping: &PieceMapping, occupied: u64) -> bool {
mapping.piece_square[31] == Some(60) && mapping.piece_square[24] == Some(56) && (occupied & ((1u64 << 57) | (1u64 << 58) | (1u64 << 59))) == 0 }
pub fn do_black_queenside(mapping: &mut PieceMapping, occupied: &mut u64) {
mapping.square_piece[60] = None;
mapping.square_piece[58] = Some(31);
mapping.piece_square[31] = Some(58);
*occupied &= !(1u64 << 60);
*occupied |= 1u64 << 58;
mapping.square_piece[56] = None;
mapping.square_piece[59] = Some(24);
mapping.piece_square[24] = Some(59);
*occupied &= !(1u64 << 56);
*occupied |= 1u64 << 59;
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::board::{encode_square, PieceMapping};
#[test]
fn white_kingside_castle_check() {
let mut mapping = PieceMapping::new_empty();
let mut occupied: u64 = 0;
mapping.place_piece(15, encode_square(0, 4)); mapping.place_piece(9, encode_square(0, 7)); occupied |= (1u64 << 4) | (1u64 << 7);
assert!(CastlingLogic::can_white_kingside(&mapping, occupied));
CastlingLogic::do_white_kingside(&mut mapping, &mut occupied);
assert_eq!(mapping.piece_square[15], Some(6)); assert_eq!(mapping.piece_square[9], Some(5)); }
#[test]
fn black_queenside_castle_check() {
let mut mapping = PieceMapping::new_empty();
let mut occupied: u64 = 0;
mapping.place_piece(31, encode_square(7, 4)); mapping.place_piece(24, encode_square(7, 0)); occupied |= (1u64 << 60) | (1u64 << 56);
assert!(CastlingLogic::can_black_queenside(&mapping, occupied));
CastlingLogic::do_black_queenside(&mut mapping, &mut occupied);
assert_eq!(mapping.piece_square[31], Some(58)); assert_eq!(mapping.piece_square[24], Some(59)); }
}