chess-engine/src/movegen/sliders.rs
2025-11-19 22:05:37 +01:00

132 lines
5.4 KiB
Rust

use crate::board::*;
use crate::r#move::*;
use crate::square::SQUARES;
use super::tables::*;
pub fn generate_rook_moves(board: &Board, list: &mut MoveList) {
let mut friendly_rooks = board.pieces[PieceType::Rook as usize][board.side_to_move as usize];
while friendly_rooks > 0 {
let square_index = friendly_rooks.trailing_zeros() as usize;
let premask = PREMASKS_ROOK[square_index];
let magic = MAGICS_ROOK[square_index];
let relevant_bits = RELEVANT_BITS_ROOK[square_index];
let shift = 64 - relevant_bits;
let blockers = board.all_occupied & premask;
let attack_table = get_rook_attacks();
let magic_index = (blockers.wrapping_mul(magic)) >> shift;
let movable_squares = attack_table[square_index][magic_index as usize];
// 1. Normal moves
let mut quiet_moves = movable_squares & !board.all_occupied;
while quiet_moves > 0 {
let from = SQUARES[square_index];
let to = SQUARES[quiet_moves.trailing_zeros() as usize];
list.push(Move::new(from, to, MOVE_FLAG_QUIET));
quiet_moves &= quiet_moves - 1;
}
// 2. Captures
let mut capture_moves = movable_squares & board.occupied[!board.side_to_move as usize];
while capture_moves > 0 {
let from = SQUARES[square_index];
let to = SQUARES[capture_moves.trailing_zeros() as usize];
list.push(Move::new(from, to, MOVE_FLAG_CAPTURE));
capture_moves &= capture_moves - 1;
}
friendly_rooks &= friendly_rooks - 1;
}
}
pub fn generate_bishop_moves(board: &Board, list: &mut MoveList) {
let mut friendly_bishops = board.pieces[PieceType::Bishop as usize][board.side_to_move as usize];
while friendly_bishops > 0 {
let square_index = friendly_bishops.trailing_zeros() as usize;
let premask = PREMASKS_BISHOP[square_index];
let magic = MAGICS_BISHOP[square_index];
let relevant_bits = RELEVANT_BITS_BISHOP[square_index];
let shift = 64 - relevant_bits;
let blockers = board.all_occupied & premask;
let attack_table = get_bishop_attacks();
let magic_index = (blockers.wrapping_mul(magic)) >> shift;
let movable_squares = attack_table[square_index][magic_index as usize];
// 1. Normal moves
let mut quiet_moves = movable_squares & !board.all_occupied;
while quiet_moves > 0 {
let from = SQUARES[square_index];
let to = SQUARES[quiet_moves.trailing_zeros() as usize];
list.push(Move::new(from, to, MOVE_FLAG_QUIET));
quiet_moves &= quiet_moves - 1;
}
// 2. Captures
let mut capture_moves = movable_squares & board.occupied[!board.side_to_move as usize];
while capture_moves > 0 {
let from = SQUARES[square_index];
let to = SQUARES[capture_moves.trailing_zeros() as usize];
list.push(Move::new(from, to, MOVE_FLAG_CAPTURE));
capture_moves &= capture_moves - 1;
}
friendly_bishops &= friendly_bishops - 1;
}
}
pub fn generate_queen_moves(board: &Board, list: &mut MoveList) {
let mut friendly_queens = board.pieces[PieceType::Queen as usize][board.side_to_move as usize];
while friendly_queens > 0 {
let square_index = friendly_queens.trailing_zeros() as usize;
// --- 1. Get Rook Attacks ---
let rook_premask = PREMASKS_ROOK[square_index];
let rook_magic = MAGICS_ROOK[square_index];
let rook_relevant_bits = RELEVANT_BITS_ROOK[square_index];
let rook_shift = 64 - rook_relevant_bits;
let rook_blockers = board.all_occupied & rook_premask;
let rook_attack_table = get_rook_attacks();
let rook_magic_index = (rook_blockers.wrapping_mul(rook_magic)) >> rook_shift;
let rook_moves = rook_attack_table[square_index][rook_magic_index as usize];
// --- 2. Get Bishop Attacks ---
let bishop_premask = PREMASKS_BISHOP[square_index];
let bishop_magic = MAGICS_BISHOP[square_index];
let bishop_relevant_bits = RELEVANT_BITS_BISHOP[square_index];
let bishop_shift = 64 - bishop_relevant_bits;
let bishop_blockers = board.all_occupied & bishop_premask;
let bishop_attack_table = get_bishop_attacks();
let bishop_magic_index = (bishop_blockers.wrapping_mul(bishop_magic)) >> bishop_shift;
let bishop_moves = bishop_attack_table[square_index][bishop_magic_index as usize];
// --- 3. Combine Attacks ---
let movable_squares = rook_moves | bishop_moves;
// --- 4. Generate Moves (Identical to Rook/Bishop) ---
// 4a. Normal moves
let mut quiet_moves = movable_squares & !board.all_occupied;
while quiet_moves > 0 {
let from = SQUARES[square_index];
let to = SQUARES[quiet_moves.trailing_zeros() as usize];
list.push(Move::new(from, to, MOVE_FLAG_QUIET));
quiet_moves &= quiet_moves - 1;
}
// 4b. Captures
let mut capture_moves = movable_squares & board.occupied[!board.side_to_move as usize];
while capture_moves > 0 {
let from = SQUARES[square_index];
let to = SQUARES[capture_moves.trailing_zeros() as usize];
list.push(Move::new(from, to, MOVE_FLAG_CAPTURE));
capture_moves &= capture_moves - 1;
}
friendly_queens &= friendly_queens - 1;
}
}