add dual impl for bitboard (bitvec and standard)
This commit is contained in:
parent
a759f9f615
commit
5499628be0
@ -18,9 +18,12 @@ debug = true
|
||||
|
||||
lto = true
|
||||
|
||||
[features]
|
||||
bitvec = [ "dep:bitvec" ]
|
||||
|
||||
[dependencies]
|
||||
arrayvec = "0.7"
|
||||
bitvec = "1"
|
||||
bitvec = { version = "1", optional = true }
|
||||
either = "1.13"
|
||||
indicatif = "0.17"
|
||||
lazy_static = "1.5"
|
||||
|
||||
@ -1,16 +1,27 @@
|
||||
use crate::board::{BOARD_AREA, BOARD_SIZE};
|
||||
use bitvec::prelude::*;
|
||||
use static_assertions::const_assert;
|
||||
|
||||
// quick explanation for the dual-nature of [`BitBoard`]
|
||||
// There's both a `bitvec` impl (which is variable length)
|
||||
// and a `native` impl which uses a u64 as the backing type
|
||||
// the `native` impl is ~15% faster (in non-BitBoard specific benchmarks)
|
||||
// `bitvec` is only really useful if you're using esoteric board sizes
|
||||
|
||||
#[cfg(feature = "bitvec")]
|
||||
use bitvec::prelude::*;
|
||||
|
||||
#[cfg(feature = "bitvec")]
|
||||
pub type BitBoardInner = BitArr!(for BOARD_AREA, in u64, Lsb0);
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
pub type BitBoardInner = u64;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct BitBoard(BitBoardInner);
|
||||
|
||||
// BitBoard should be big enough to fit all points on the board
|
||||
const_assert!(std::mem::size_of::<BitBoard>() * 8 >= BOARD_AREA);
|
||||
|
||||
/// Backing Type of BitBoard
|
||||
type BBBaseType = u64;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub struct BitBoard(BitArr!(for BOARD_AREA, in BBBaseType, Lsb0));
|
||||
|
||||
impl Default for BitBoard {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
@ -18,22 +29,61 @@ impl Default for BitBoard {
|
||||
}
|
||||
|
||||
impl BitBoard {
|
||||
#[cfg(feature = "bitvec")]
|
||||
pub const fn new() -> Self {
|
||||
Self(bitarr!(BBBaseType, Lsb0; 0; BOARD_AREA))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
pub const fn new() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
pub const fn get(&self, row: usize, col: usize) -> bool {
|
||||
((self.0 >> Self::get_index(row, col)) & 1) != 0
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
pub const fn set(&mut self, row: usize, col: usize, value: bool) {
|
||||
let index = Self::get_index(row, col);
|
||||
if value {
|
||||
self.set_bit(index); // Set the bit at (row, col) to 1
|
||||
} else {
|
||||
self.clear_bit(index); // Clear the bit at (row, col)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
const fn clear_bit(&mut self, index: usize) {
|
||||
self.0 &= !(1 << index)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
const fn set_bit(&mut self, index: usize) {
|
||||
self.0 |= 1 << index
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "bitvec"))]
|
||||
pub const fn count(&self) -> usize {
|
||||
self.0.count_ones() as usize
|
||||
}
|
||||
|
||||
const fn get_index(row: usize, col: usize) -> usize {
|
||||
row * BOARD_SIZE + col
|
||||
}
|
||||
|
||||
#[cfg(feature = "bitvec")]
|
||||
pub fn get(&self, row: usize, col: usize) -> bool {
|
||||
self.0[Self::get_index(row, col)]
|
||||
}
|
||||
|
||||
#[cfg(feature = "bitvec")]
|
||||
pub fn set(&mut self, row: usize, col: usize, value: bool) {
|
||||
self.0.set(Self::get_index(row, col), value);
|
||||
}
|
||||
|
||||
#[cfg(feature = "bitvec")]
|
||||
pub fn count(&self) -> usize {
|
||||
self.0.count_ones()
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ use std::{cmp::Ordering, fmt};
|
||||
pub const BOARD_SIZE: usize = 8;
|
||||
|
||||
/// Area of the board
|
||||
#[allow(dead_code)]
|
||||
pub const BOARD_AREA: usize = BOARD_SIZE * BOARD_SIZE;
|
||||
|
||||
/// A chain of positions across the board
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user