chessfriend/board/src/castle/rights.rs

93 lines
3.3 KiB
Rust
Raw Normal View History

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));
}
}