[board] Remove Flags struct, replace it with Castle and supporting structs

Encapsulate castling rights within a small module. Castle provides the API to the
rest of the board package. Rights encodes the castling rights for each player.
Parameters defines castling parameters for each player.
This commit is contained in:
Eryn Wells 2025-05-02 15:03:48 -07:00
parent 9f2bfc0457
commit 0b100d5f14
5 changed files with 210 additions and 203 deletions

View file

@ -0,0 +1,92 @@
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));
}
}