81 lines
2.6 KiB
Rust
81 lines
2.6 KiB
Rust
use super::Castle;
|
|
use chessfriend_core::Color;
|
|
use std::fmt;
|
|
|
|
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
|
pub struct Rights(u8);
|
|
|
|
impl Rights {
|
|
/// Returns `true` if the player has the right to castle on the given side
|
|
/// of the board.
|
|
///
|
|
/// A player retains the right to castle on a particular side of the board
|
|
/// as long as they have not moved their king, or the rook on that side of
|
|
/// the board.
|
|
#[must_use]
|
|
pub fn is_set(self, color: Color, castle: Castle) -> bool {
|
|
(self.0 & (1 << Self::flag_offset(color, castle))) != 0
|
|
}
|
|
|
|
pub fn set(&mut self, color: Color, castle: Castle) {
|
|
self.0 |= 1 << Self::flag_offset(color, castle);
|
|
}
|
|
|
|
pub fn clear(&mut self, color: Color, castle: Castle) {
|
|
self.0 &= !(1 << Self::flag_offset(color, castle));
|
|
}
|
|
|
|
pub fn clear_all(&mut self) {
|
|
self.0 = 0;
|
|
}
|
|
|
|
fn flag_offset(color: Color, castle: Castle) -> usize {
|
|
((color as usize) << 1) + castle as usize
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for Rights {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "Flags({:08b})", self.0)
|
|
}
|
|
}
|
|
|
|
impl Default for Rights {
|
|
fn default() -> Self {
|
|
Self(0b0000_1111)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn bitfield_offsets() {
|
|
assert_eq!(Rights::flag_offset(Color::White, Castle::KingSide), 0);
|
|
assert_eq!(Rights::flag_offset(Color::White, Castle::QueenSide), 1);
|
|
assert_eq!(Rights::flag_offset(Color::Black, Castle::KingSide), 2);
|
|
assert_eq!(Rights::flag_offset(Color::Black, Castle::QueenSide), 3);
|
|
}
|
|
|
|
#[test]
|
|
fn default_rights() {
|
|
let mut rights = Rights::default();
|
|
assert!(rights.is_set(Color::White, Castle::KingSide));
|
|
assert!(rights.is_set(Color::White, Castle::QueenSide));
|
|
assert!(rights.is_set(Color::Black, Castle::KingSide));
|
|
assert!(rights.is_set(Color::Black, Castle::QueenSide));
|
|
|
|
rights.clear(Color::White, Castle::QueenSide);
|
|
assert!(rights.is_set(Color::White, Castle::KingSide));
|
|
assert!(!rights.is_set(Color::White, Castle::QueenSide));
|
|
assert!(rights.is_set(Color::Black, Castle::KingSide));
|
|
assert!(rights.is_set(Color::Black, Castle::QueenSide));
|
|
|
|
rights.set(Color::White, Castle::QueenSide);
|
|
assert!(rights.is_set(Color::White, Castle::KingSide));
|
|
assert!(rights.is_set(Color::White, Castle::QueenSide));
|
|
assert!(rights.is_set(Color::Black, Castle::KingSide));
|
|
assert!(rights.is_set(Color::Black, Castle::QueenSide));
|
|
}
|
|
}
|