73 lines
1.7 KiB
Rust
73 lines
1.7 KiB
Rust
|
/// An enum representing the type of a piece.
|
||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||
|
pub enum Piece {
|
||
|
King,
|
||
|
Queen,
|
||
|
Rook,
|
||
|
Bishop,
|
||
|
Knight,
|
||
|
Pawn,
|
||
|
}
|
||
|
|
||
|
impl Piece {
|
||
|
/// The number of [Piece] variants.
|
||
|
pub const NUM_VARIANTS: usize = 6;
|
||
|
|
||
|
const ALL: [Self; Self::NUM_VARIANTS] = [
|
||
|
Self::King,
|
||
|
Self::Queen,
|
||
|
Self::Rook,
|
||
|
Self::Bishop,
|
||
|
Self::Knight,
|
||
|
Self::Pawn,
|
||
|
];
|
||
|
|
||
|
/// Iterate over all piece types.
|
||
|
pub fn iter() -> impl Iterator<Item = Self> {
|
||
|
Self::ALL.iter().cloned()
|
||
|
}
|
||
|
|
||
|
/// Convert from a piece index into a [Piece] type.
|
||
|
#[inline(always)]
|
||
|
pub fn from_index(index: usize) -> Self {
|
||
|
assert!(index < Self::NUM_VARIANTS);
|
||
|
// SAFETY: we know the value is in-bounds
|
||
|
unsafe { Self::from_index_unchecked(index) }
|
||
|
}
|
||
|
|
||
|
/// Convert from a piece index into a [Piece] type, no bounds checking.
|
||
|
///
|
||
|
/// # Safety
|
||
|
///
|
||
|
/// Should only be called with values that can be output by [Piece::index()].
|
||
|
#[inline(always)]
|
||
|
pub unsafe fn from_index_unchecked(index: usize) -> Self {
|
||
|
std::mem::transmute(index as u8)
|
||
|
}
|
||
|
|
||
|
/// Return the index of a given [Piece].
|
||
|
#[inline(always)]
|
||
|
pub fn index(self) -> usize {
|
||
|
self as usize
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod test {
|
||
|
use super::*;
|
||
|
|
||
|
#[test]
|
||
|
fn from_index() {
|
||
|
assert_eq!(Piece::from_index(0), Piece::King);
|
||
|
assert_eq!(Piece::from_index(1), Piece::Queen);
|
||
|
assert_eq!(Piece::from_index(5), Piece::Pawn);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn index() {
|
||
|
assert_eq!(Piece::King.index(), 0);
|
||
|
assert_eq!(Piece::Queen.index(), 1);
|
||
|
assert_eq!(Piece::Pawn.index(), 5);
|
||
|
}
|
||
|
}
|