use crate::board::PieceMapping;
pub struct EnPassantLogic;
impl EnPassantLogic {
pub fn compute_ep_target(src: u8, dest: u8, side: u8) -> Option<u8> {
let src_rank = src >> 3;
let dst_rank = dest >> 3;
if side == 0 && dst_rank == src_rank + 2 {
Some(dest - 8)
} else if side == 1 && dst_rank + 2 == src_rank {
Some(dest + 8)
} else {
None
}
}
pub fn do_ep_capture(
mapping: &mut PieceMapping,
occupied: &mut u64,
ep_target: u8,
side: u8,
) -> Option<u8> {
let captured_sq = if side == 0 { ep_target - 8 } else { ep_target + 8 };
if let Some(opp_pid) = mapping.who_on_square(captured_sq) {
mapping.remove_piece(opp_pid);
*occupied &= !(1u64 << (captured_sq as u64));
return Some(opp_pid);
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::board::{encode_piece, encode_square, PieceMapping};
#[test]
fn compute_and_do_ep_capture() {
let mut mapping = PieceMapping::new_empty();
let mut occupied: u64 = 0;
let white_pawn = encode_piece(0, true, 4, 0);
let black_pawn = encode_piece(1, true, 3, 0);
mapping.place_piece(white_pawn, encode_square(4, 4));
mapping.place_piece(black_pawn, encode_square(4, 3));
occupied |= (1u64 << 36) | (1u64 << 35);
let ep_target = EnPassantLogic::compute_ep_target(encode_square(6, 3), encode_square(4, 3), 1);
assert_eq!(ep_target, Some(encode_square(5, 3)));
mapping.remove_piece(white_pawn);
mapping.place_piece(white_pawn, encode_square(5, 3));
occupied &= !(1u64 << 36);
occupied |= 1u64 << 43;
let captured = EnPassantLogic::do_ep_capture(
&mut mapping,
&mut occupied,
ep_target.unwrap(),
0,
);
assert_eq!(captured, Some(black_pawn));
assert!(mapping.who_on_square(encode_square(4, 3)).is_none()); }
}