1个不稳定发布
0.1.0 | 2024年5月11日 |
---|
#909 在 游戏 中
20KB
287 行
Quadboard
Quad-Bitboards数据结构的类型安全SIMD实现,最初作为konig引擎的一部分编写。
此crate的稳定性取决于portable_simd
特性的稳定性(跟踪问题 #86656),尽管在中间可以通过cargo标志解决这个问题。
使用方法
假设你想使用quadboard以通常方式表示棋盘状态,以下是这样定义棋子的
#[repr(u8)]
#[derive(Default)]
enum Color {
#[default]
Black = 0b0000,
White = 0b1000,
}
#[repr(u8)]
#[derive(Default)]
enum Kind {
#[default]
None = 0b000,
Pawn = 0b001,
Rook = 0b010,
Knight = 0b011,
Bishop = 0b100,
Queen = 0b101,
King = 0b110,
}
#[derive(Default)]
struct Piece {
color: Color,
kind: Kind,
}
这种特定的编码可以通过仅取其字段按位与来将一个棋子放入一个nibble中,因此我们可以定义以下编码
// going from a Piece to a Nibble is fairly simple
impl From<Piece> for Nibble {
fn from(value: Piece) -> Self {
let nibble = (value.color as u8) & (value.kind as u8);
unsafe { Nibble::new_unchecked(nibble) }
}
}
// in reverse, we have a few more problems to deal with:
// 1. 0b0111 and 0b1111 don't correpond to specific pieces, and;
// 2. 0b1000 and 0b0000 map to the same piece.
//
// these are details that should encourage you to use a different
// encoding scheme –– there's surprising room for improvement
impl From<Nibble> for Piece {
fn from(value: Nibble) -> Self {
// if you trust your encoding, std::mem::transmute
// is probably the fastest decoding implementation
let byte: u8 = value.get();
// match against the significand of
// the nibble to get the color
let color: Color = match byte >> 3 {
0 => Color::Black,
1 => Color::White,
_ => unreachable!,
};
let kind: Kind = match byte & (!0b111) {
// left as an exercise to the reader...
_ => todo!(),
}
Self { color, kind }
}
}
就是这样!这是使用Quadboard<Piece>
所需的最小内容,主要使用get
和set
方法以及它们的非安全_unchecked
等效方法。
// create a quadboard filled with Piece::default()
let mut qb = Quadboard::<Piece>::default();
// insert some pieces
qb.set(7u8.try_into().unwrap(), Piece { color: Color::White, kind: Kind::Queen });
qb.set(3u8.try_into().unwrap(), Piece { color: Color::Black, kind: Kind::Pawn });
qb.set(25u8.try_into().unwrap(), Piece { color: Color::White, kind: Kind::Bishop });
qb.set(34u8.try_into().unwrap(), Piece { color: Color::Black, kind: Kind::Rook });
// and read them out
assert_eq!(
qb.get(7u8.try_into().unwrap()),
Piece { color: Color::White, kind: Kind::Queen }
)
// a quadboard is defined at all indices at all times
assert_eq!(
qb.get(0u8.try_into().unwrap()),
Piece { color: Color::Black, kind: Kind::None }
)
依赖关系
~325–790KB
~19K SLoC