[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:
Eryn Wells 2025-06-18 23:44:40 +00:00
parent 933924d37a
commit 4ce7e89cdb
8 changed files with 177 additions and 124 deletions

View file

@ -1,13 +1,13 @@
// Eryn Wells <eryn@erynwells.me>
use crate::{
PieceSet, castle,
CastleRights, PieceSet,
display::DiagramFormatter,
piece_sets::{PlacePieceError, PlacePieceStrategy},
zobrist::{ZobristHash, ZobristState},
};
use chessfriend_bitboard::BitBoard;
use chessfriend_core::{Color, Piece, Shape, Square, Wing};
use chessfriend_core::{Color, Piece, Shape, Square};
use std::sync::Arc;
pub type HalfMoveClock = u32;
@ -17,7 +17,7 @@ pub type FullMoveClock = u32;
pub struct Board {
active_color: Color,
pieces: PieceSet,
castling_rights: castle::Rights,
castling_rights: CastleRights,
en_passant_target: Option<Square>,
pub half_move_clock: HalfMoveClock,
pub full_move_number: FullMoveClock,
@ -92,59 +92,27 @@ impl Board {
impl Board {
#[must_use]
pub fn castling_rights(&self) -> castle::Rights {
self.castling_rights
pub fn castling_rights(&self) -> &CastleRights {
&self.castling_rights
}
pub fn set_castling_rights(&mut self, rights: castle::Rights) {
pub(crate) fn castling_rights_mut(&mut self) -> &mut CastleRights {
&mut self.castling_rights
}
/// Replace castling rights with new rights wholesale.
pub fn set_castling_rights(&mut self, rights: CastleRights) {
if rights == self.castling_rights {
return;
}
let old_rights = self.castling_rights;
self.castling_rights = rights;
self.update_zobrist_hash_castling_rights(old_rights);
}
#[must_use]
pub fn active_color_has_castling_right(&self, wing: Wing) -> bool {
self.color_has_castling_right_unwrapped(self.active_color, wing)
}
#[must_use]
pub fn color_has_castling_right(&self, color: Option<Color>, wing: Wing) -> bool {
self.color_has_castling_right_unwrapped(self.unwrap_color(color), wing)
}
#[must_use]
pub fn color_has_castling_right_unwrapped(&self, color: Color, wing: Wing) -> bool {
self.castling_rights.color_has_right(color, wing)
}
pub fn grant_castling_right(&mut self, color: Color, wing: Wing) {
let old_rights = self.castling_rights;
self.castling_rights.grant(color, wing);
self.update_zobrist_hash_castling_rights(old_rights);
}
pub fn revoke_all_castling_rights(&mut self) {
let old_rights = self.castling_rights;
self.castling_rights.revoke_all();
self.update_zobrist_hash_castling_rights(old_rights);
}
pub fn revoke_castling_right(&mut self, color: Option<Color>, wing: Wing) {
let color = self.unwrap_color(color);
self.revoke_castling_right_unwrapped(color, wing);
}
pub fn revoke_castling_right_unwrapped(&mut self, color: Color, wing: Wing) {
let old_rights = self.castling_rights;
self.castling_rights.revoke(color, wing);
self.update_zobrist_hash_castling_rights(old_rights);
}
fn update_zobrist_hash_castling_rights(&mut self, old_rights: castle::Rights) {
pub(crate) fn update_zobrist_hash_castling_rights(&mut self, old_rights: CastleRights) {
let new_rights = self.castling_rights;
if old_rights == new_rights {
return;
@ -154,6 +122,18 @@ impl Board {
zobrist.update_modifying_castling_rights(new_rights, old_rights);
}
}
pub(crate) fn castling_king(&self, square: Square) -> Option<Piece> {
let active_color = self.active_color();
self.get_piece(square)
.filter(|piece| piece.color == active_color && piece.is_king())
}
pub(crate) fn castling_rook(&self, square: Square) -> Option<Piece> {
let active_color = self.active_color();
self.get_piece(square)
.filter(|piece| piece.color == active_color && piece.is_rook())
}
}
impl Board {