macro_rules! shift_up {
($exp:expr) => {
$exp >> super::constants::BOARD_WIDTH
};
}
macro_rules! shift_down {
($exp:expr) => {
$exp << super::constants::BOARD_WIDTH
};
}
macro_rules! shift_left {
($exp:expr) => {
$exp >> 1
};
}
macro_rules! shift_right {
($exp:expr) => {
$exp << 1
};
}
macro_rules! shift_pieces_up {
($exp:expr) => {
shift_up!($exp & !super::piece_board::TOP_ROW_MASK)
};
}
macro_rules! shift_pieces_right {
($exp:expr) => {
shift_right!($exp & !super::piece_board::RIGHT_COLUMN_MASK)
};
}
macro_rules! shift_pieces_down {
($exp:expr) => {
shift_down!($exp & !super::piece_board::BOTTOM_ROW_MASK)
};
}
macro_rules! shift_pieces_left {
($exp:expr) => {
shift_left!($exp & !super::piece_board::LEFT_COLUMN_MASK)
};
}
pub fn single_bit_index(bit: u128) -> usize {
bit.trailing_zeros() as usize
}
pub fn for_each_bit_idx<F: FnMut(u32)>(board: u64, mut f: F) {
let mut board = board;
while board != 0 {
let bit_idx = board.trailing_zeros();
f(bit_idx);
board ^= 1 << bit_idx;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_single_bit_index_first_bit() {
let bit = 0b1;
let expected_bit_index = 0;
let actual_bit_index = single_bit_index(bit);
assert_eq!(expected_bit_index, actual_bit_index);
}
#[test]
fn test_single_bit_index_second_bit() {
let bit = 0b10;
let expected_bit_index = 1;
let actual_bit_index = single_bit_index(bit);
assert_eq!(expected_bit_index, actual_bit_index);
}
#[test]
fn test_single_bit_index_third_bit() {
let bit = 0b100;
let expected_bit_index = 2;
let actual_bit_index = single_bit_index(bit);
assert_eq!(expected_bit_index, actual_bit_index);
}
#[test]
fn test_single_bit_index_last_bit() {
let bit = 0b1 << 127;
let expected_bit_index = 127;
let actual_bit_index = single_bit_index(bit);
assert_eq!(expected_bit_index, actual_bit_index);
}
}