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. pub fn player_has_right_to_castle(self, color: Color, castle: Castle) -> bool { (self.0 & (1 << Self::_player_has_right_to_castle_flag_offset(color, castle))) != 0 } pub fn set_player_has_right_to_castle_flag(&mut self, color: Color, castle: Castle) { self.0 |= 1 << Self::_player_has_right_to_castle_flag_offset(color, castle); } pub fn clear_player_has_right_to_castle_flag(&mut self, color: Color, castle: Castle) { self.0 &= !(1 << Self::_player_has_right_to_castle_flag_offset(color, castle)); } pub fn clear_all(&mut self) { self.0 &= 0b1111_1100; } fn _player_has_right_to_castle_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 castling_rights() { assert_eq!( Rights::_player_has_right_to_castle_flag_offset(Color::White, Castle::KingSide), 0 ); assert_eq!( Rights::_player_has_right_to_castle_flag_offset(Color::White, Castle::QueenSide), 1 ); assert_eq!( Rights::_player_has_right_to_castle_flag_offset(Color::Black, Castle::KingSide), 2 ); assert_eq!( Rights::_player_has_right_to_castle_flag_offset(Color::Black, Castle::QueenSide), 3 ); } #[test] fn default_rights() { let mut rights = Rights::default(); assert!(rights.player_has_right_to_castle(Color::White, Castle::KingSide)); assert!(rights.player_has_right_to_castle(Color::White, Castle::QueenSide)); assert!(rights.player_has_right_to_castle(Color::Black, Castle::KingSide)); assert!(rights.player_has_right_to_castle(Color::Black, Castle::QueenSide)); rights.clear_player_has_right_to_castle_flag(Color::White, Castle::QueenSide); assert!(rights.player_has_right_to_castle(Color::White, Castle::KingSide)); assert!(!rights.player_has_right_to_castle(Color::White, Castle::QueenSide)); assert!(rights.player_has_right_to_castle(Color::Black, Castle::KingSide)); assert!(rights.player_has_right_to_castle(Color::Black, Castle::QueenSide)); rights.set_player_has_right_to_castle_flag(Color::White, Castle::QueenSide); assert!(rights.player_has_right_to_castle(Color::White, Castle::KingSide)); assert!(rights.player_has_right_to_castle(Color::White, Castle::QueenSide)); assert!(rights.player_has_right_to_castle(Color::Black, Castle::KingSide)); assert!(rights.player_has_right_to_castle(Color::Black, Castle::QueenSide)); } }