93 lines
3.3 KiB
Rust
93 lines
3.3 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.
|
||
|
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));
|
||
|
}
|
||
|
}
|