132 lines
5.4 KiB
Rust
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;
|
|
}
|
|
}
|