Move 'Magic' into 'seer::movegen::magic'

This commit is contained in:
Bruno BELANYI 2022-07-22 18:50:44 +02:00
parent 7dbe48ad23
commit d97e7d646e
3 changed files with 33 additions and 35 deletions

View file

@ -1,21 +0,0 @@
use crate::board::Bitboard;
/// A type representing the magic board indexing a given [Square].
pub struct Magic {
/// Magic number.
pub(crate) magic: u64,
/// Base offset into the magic square table.
pub(crate) offset: usize,
/// Mask to apply to the blocker board before applying the magic.
pub(crate) mask: Bitboard,
/// Length of the resulting mask after applying the magic.
pub(crate) shift: u8,
}
impl Magic {
pub fn get_index(&self, blockers: Bitboard) -> usize {
let relevant_occupancy = (blockers & self.mask).0;
let base_index = ((relevant_occupancy.wrapping_mul(self.magic)) >> self.shift) as usize;
base_index + self.offset
}
}

View file

@ -1,2 +1,21 @@
pub mod magic; use crate::board::Bitboard;
pub use magic::*;
/// A type representing the magic board indexing a given [crate::board::Square].
pub struct Magic {
/// Magic number.
pub(crate) magic: u64,
/// Base offset into the magic square table.
pub(crate) offset: usize,
/// Mask to apply to the blocker board before applying the magic.
pub(crate) mask: Bitboard,
/// Length of the resulting mask after applying the magic.
pub(crate) shift: u8,
}
impl Magic {
pub fn get_index(&self, blockers: Bitboard) -> usize {
let relevant_occupancy = (blockers & self.mask).0;
let base_index = ((relevant_occupancy.wrapping_mul(self.magic)) >> self.shift) as usize;
base_index + self.offset
}
}

View file

@ -22,42 +22,42 @@ fn generate_magics(
mask_fn: impl Fn(Square) -> Bitboard, mask_fn: impl Fn(Square) -> Bitboard,
moves_fn: impl Fn(Square, Bitboard) -> Bitboard, moves_fn: impl Fn(Square, Bitboard) -> Bitboard,
) -> MagicGenerationType { ) -> MagicGenerationType {
let mut offset = 0;
let mut magics = Vec::new(); let mut magics = Vec::new();
let mut boards = Vec::new(); let mut boards = Vec::new();
for square in Square::iter() { for square in Square::iter() {
let mask = mask_fn(square); let mask = mask_fn(square);
let mut candidate: Magic; let mut candidate: Magic;
let potential_occupancy: Vec<_> = mask.iter_power_set().collect();
let moves_len = potential_occupancy.len(); let occupancy_to_moves: Vec<_> = mask
.iter_power_set()
.map(|occupancy| (occupancy, moves_fn(square, occupancy)))
.collect();
'candidate_search: loop { 'candidate_search: loop {
candidate = Magic { candidate = Magic {
magic: magic_candidate(rng), magic: magic_candidate(rng),
offset, offset: 0,
mask, mask,
shift: (64 - mask.count()) as u8, shift: (64 - mask.count()) as u8,
}; };
let mut candidate_moves = Vec::new(); let mut candidate_moves = vec![Bitboard::EMPTY; occupancy_to_moves.len()];
candidate_moves.resize(moves_len, Bitboard::EMPTY);
for occupancy in potential_occupancy.iter().cloned() { for (occupancy, moves) in occupancy_to_moves.iter().cloned() {
let index = candidate.get_index(occupancy); let index = candidate.get_index(occupancy);
let moves = moves_fn(square, occupancy); // Non-constructive collision, try with another candidate
if candidate_moves[index] != Bitboard::EMPTY && candidate_moves[index] != moves { if candidate_moves[index] != Bitboard::EMPTY && candidate_moves[index] != moves {
continue 'candidate_search; continue 'candidate_search;
} }
candidate_moves[index] = moves; candidate_moves[index] = moves;
} }
// We have filled all candidate boards, record the correct offset and add the moves
candidate.offset = boards.len();
boards.append(&mut candidate_moves); boards.append(&mut candidate_moves);
magics.push(candidate);
break; break;
} }
magics.push(candidate);
offset += moves_len;
} }
(magics, boards) (magics, boards)