Add 'TryInto<Square>' for 'Bitboard'

This commit is contained in:
Bruno BELANYI 2022-07-29 19:26:31 +02:00
parent bc67ee3e9a
commit 6976c60fe6
2 changed files with 55 additions and 0 deletions

View file

@ -0,0 +1,19 @@
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum IntoSquareError {
/// The board is empty.
EmptyBoard,
/// The board contains more than one square.
TooManySquares,
}
impl std::fmt::Display for IntoSquareError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let error_msg = match self {
Self::EmptyBoard => "The board is empty",
Self::TooManySquares => "The board contains more than one square",
};
write!(f, "{}", error_msg)
}
}
impl std::error::Error for IntoSquareError {}

View file

@ -1,6 +1,8 @@
use super::Square;
use crate::utils::static_assert;
mod error;
use error::*;
mod iterator;
use iterator::*;
mod superset;
@ -102,6 +104,21 @@ impl IntoIterator for Bitboard {
}
}
/// If the given [Bitboard] is a singleton piece on a board, return the [Square] that it is
/// occupying. Otherwise return `None`.
impl TryInto<Square> for Bitboard {
type Error = IntoSquareError;
fn try_into(self) -> Result<Square, Self::Error> {
let index = match self.count() {
1 => self.0.trailing_zeros() as usize,
0 => return Err(IntoSquareError::EmptyBoard),
_ => return Err(IntoSquareError::TooManySquares),
};
Ok(Square::from_index(index))
}
}
/// Treat bitboard as a set of squares, shift each square's index left by the amount given.
impl std::ops::Shl<usize> for Bitboard {
type Output = Bitboard;
@ -461,4 +478,23 @@ mod test {
1 << 8
);
}
#[test]
fn into_square() {
for square in Square::iter() {
assert_eq!(square.into_bitboard().try_into(), Ok(square));
}
}
#[test]
fn into_square_invalid() {
assert_eq!(
TryInto::<Square>::try_into(Bitboard::EMPTY),
Err(IntoSquareError::EmptyBoard)
);
assert_eq!(
TryInto::<Square>::try_into(Square::A1 | Square::A2),
Err(IntoSquareError::TooManySquares)
)
}
}