[board, explorer, moves] Clean up the castling rights API
Reorganize castling rights API on Board into methods named according to
conventions applied to other API.
Board::has_castling_right
Board::has_castling_right_active
Board::has_castling_right_unwrapped
These all check if a color has the right to castle on a particular side
(wing) of the board. The first takes an Option<Color>, the latter two
operate on bare Colors: the active color, or an explicit Color.
Board::grant_castling_right
Board::grant_castling_right_active
Board::grant_castling_right_unwrapped
Grant castling rights to a color. Color arguments follow the pattern above.
Board::revoke_castling_right
Board::revoke_castling_right_active
Board::revoke_castling_right_unwrapped
Revoke castling rights from a color. Color arguments follow the pattern
above.
The latter two groups of methods take a new CastleRightsOption type that
specifies either a single Wing or All.
Rework the implementation of CastleRights to take a CastleRightsOption. Update
the unit tests and make sure everything builds.
This commit is contained in:
parent
933924d37a
commit
4ce7e89cdb
8 changed files with 177 additions and 124 deletions
|
|
@ -1,6 +1,14 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use chessfriend_core::{Color, Wing};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CastleRightsOption {
|
||||
Wing(Wing),
|
||||
All,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub struct Rights(u8);
|
||||
|
||||
|
|
@ -12,16 +20,16 @@ impl Rights {
|
|||
/// as long as they have not moved their king, or the rook on that side of
|
||||
/// the board.
|
||||
#[must_use]
|
||||
pub fn color_has_right(self, color: Color, wing: Wing) -> bool {
|
||||
(self.0 & (1 << Self::flag_offset(color, wing))) != 0
|
||||
pub fn get(self, color: Color, option: CastleRightsOption) -> bool {
|
||||
(self.0 & Self::flags(color, option)) != 0
|
||||
}
|
||||
|
||||
pub fn grant(&mut self, color: Color, wing: Wing) {
|
||||
self.0 |= 1 << Self::flag_offset(color, wing);
|
||||
pub fn grant(&mut self, color: Color, option: CastleRightsOption) {
|
||||
self.0 |= Self::flags(color, option);
|
||||
}
|
||||
|
||||
pub fn revoke(&mut self, color: Color, wing: Wing) {
|
||||
self.0 &= !(1 << Self::flag_offset(color, wing));
|
||||
pub fn revoke(&mut self, color: Color, option: CastleRightsOption) {
|
||||
self.0 &= !Self::flags(color, option);
|
||||
}
|
||||
|
||||
/// Revoke castling rights for all colors and all sides of the board.
|
||||
|
|
@ -31,14 +39,14 @@ impl Rights {
|
|||
}
|
||||
|
||||
impl Rights {
|
||||
pub(crate) fn as_index(&self) -> usize {
|
||||
pub(crate) fn as_index(self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl Rights {
|
||||
fn flag_offset(color: Color, wing: Wing) -> usize {
|
||||
((color as usize) << 1) + wing as usize
|
||||
const fn flags(color: Color, option: CastleRightsOption) -> u8 {
|
||||
option.as_flags() << (color as u8 * 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,36 +62,55 @@ impl Default for Rights {
|
|||
}
|
||||
}
|
||||
|
||||
impl CastleRightsOption {
|
||||
#[must_use]
|
||||
pub const fn as_flags(self) -> u8 {
|
||||
match self {
|
||||
Self::Wing(wing) => 1 << (wing as u8),
|
||||
Self::All => (1 << Wing::KingSide as u8) | (1 << Wing::QueenSide as u8),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Wing> for CastleRightsOption {
|
||||
fn from(value: Wing) -> Self {
|
||||
Self::Wing(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bitfield_offsets() {
|
||||
assert_eq!(Rights::flag_offset(Color::White, Wing::KingSide), 0);
|
||||
assert_eq!(Rights::flag_offset(Color::White, Wing::QueenSide), 1);
|
||||
assert_eq!(Rights::flag_offset(Color::Black, Wing::KingSide), 2);
|
||||
assert_eq!(Rights::flag_offset(Color::Black, Wing::QueenSide), 3);
|
||||
assert_eq!(Rights::flags(Color::White, Wing::KingSide.into()), 1);
|
||||
assert_eq!(Rights::flags(Color::White, Wing::QueenSide.into()), 1 << 1);
|
||||
assert_eq!(Rights::flags(Color::Black, Wing::KingSide.into()), 1 << 2);
|
||||
assert_eq!(Rights::flags(Color::Black, Wing::QueenSide.into()), 1 << 3);
|
||||
|
||||
assert_eq!(Rights::flags(Color::White, CastleRightsOption::All), 0b11);
|
||||
assert_eq!(Rights::flags(Color::Black, CastleRightsOption::All), 0b1100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_rights() {
|
||||
let mut rights = Rights::default();
|
||||
assert!(rights.color_has_right(Color::White, Wing::KingSide));
|
||||
assert!(rights.color_has_right(Color::White, Wing::QueenSide));
|
||||
assert!(rights.color_has_right(Color::Black, Wing::KingSide));
|
||||
assert!(rights.color_has_right(Color::Black, Wing::QueenSide));
|
||||
assert!(rights.get(Color::White, Wing::KingSide.into()));
|
||||
assert!(rights.get(Color::White, Wing::QueenSide.into()));
|
||||
assert!(rights.get(Color::Black, Wing::KingSide.into()));
|
||||
assert!(rights.get(Color::Black, Wing::QueenSide.into()));
|
||||
|
||||
rights.revoke(Color::White, Wing::QueenSide);
|
||||
assert!(rights.color_has_right(Color::White, Wing::KingSide));
|
||||
assert!(!rights.color_has_right(Color::White, Wing::QueenSide));
|
||||
assert!(rights.color_has_right(Color::Black, Wing::KingSide));
|
||||
assert!(rights.color_has_right(Color::Black, Wing::QueenSide));
|
||||
rights.revoke(Color::White, Wing::QueenSide.into());
|
||||
assert!(rights.get(Color::White, Wing::KingSide.into()));
|
||||
assert!(!rights.get(Color::White, Wing::QueenSide.into()));
|
||||
assert!(rights.get(Color::Black, Wing::KingSide.into()));
|
||||
assert!(rights.get(Color::Black, Wing::QueenSide.into()));
|
||||
|
||||
rights.grant(Color::White, Wing::QueenSide);
|
||||
assert!(rights.color_has_right(Color::White, Wing::KingSide));
|
||||
assert!(rights.color_has_right(Color::White, Wing::QueenSide));
|
||||
assert!(rights.color_has_right(Color::Black, Wing::KingSide));
|
||||
assert!(rights.color_has_right(Color::Black, Wing::QueenSide));
|
||||
rights.grant(Color::White, Wing::QueenSide.into());
|
||||
assert!(rights.get(Color::White, Wing::KingSide.into()));
|
||||
assert!(rights.get(Color::White, Wing::QueenSide.into()));
|
||||
assert!(rights.get(Color::Black, Wing::KingSide.into()));
|
||||
assert!(rights.get(Color::Black, Wing::QueenSide.into()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue