pub type Occupied = u64;
pub type CapturedBits = u32;
#[derive(Clone, Debug)]
pub struct PieceMapping {
pub piece_square: [Option<u8>; 32],
pub square_piece: [Option<u8>; 64],
}
impl PieceMapping {
pub fn new_empty() -> PieceMapping {
PieceMapping {
piece_square: [None; 32],
square_piece: [None; 64],
}
}
pub fn place_piece(&mut self, pid: u8, sq: u8) {
let pi = pid as usize;
let sqi = sq as usize;
assert!(
self.piece_square[pi].is_none(),
"Piece {} already on board",
pid
);
assert!(
self.square_piece[sqi].is_none(),
"Square {} is already occupied",
sq
);
self.piece_square[pi] = Some(sq);
self.square_piece[sqi] = Some(pid);
}
pub fn remove_piece(&mut self, pid: u8) {
let pi = pid as usize;
if let Some(old_sq) = self.piece_square[pi] {
let sqi = old_sq as usize;
self.square_piece[sqi] = None;
}
self.piece_square[pi] = None;
}
pub fn move_piece(&mut self, pid: u8, dest: u8) {
let pi = pid as usize;
let dest_i = dest as usize;
let old_sq = self.piece_square[pi]
.expect(&format!("(move_piece) piece {} not on board", pid)) as usize;
assert!(
self.square_piece[dest_i].is_none(),
"Destination {} occupied",
dest
);
self.square_piece[old_sq] = None;
self.square_piece[dest_i] = Some(pid);
self.piece_square[pi] = Some(dest);
}
pub fn who_on_square(&self, sq: u8) -> Option<u8> {
self.square_piece[sq as usize]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mapping_basic() {
let mut pm = PieceMapping::new_empty();
pm.place_piece(5, 20);
assert_eq!(pm.piece_square[5], Some(20));
assert_eq!(pm.who_on_square(20), Some(5));
pm.move_piece(5, 30);
assert_eq!(pm.piece_square[5], Some(30));
assert_eq!(pm.who_on_square(20), None);
assert_eq!(pm.who_on_square(30), Some(5));
pm.remove_piece(5);
assert_eq!(pm.piece_square[5], None);
assert_eq!(pm.who_on_square(30), None);
}
}