[board] Replace Flags with castle::Rights
This commit is contained in:
parent
cd60a453aa
commit
bb8d5a6aa3
3 changed files with 62 additions and 19 deletions
|
@ -1,7 +1,7 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::{
|
||||
display::DiagramFormatter, piece_sets::PlacePieceError, Castle, EnPassant, Flags, MoveCounter,
|
||||
castle, display::DiagramFormatter, piece_sets::PlacePieceError, EnPassant, MoveCounter,
|
||||
PieceSet,
|
||||
};
|
||||
use chessfriend_bitboard::BitBoard;
|
||||
|
@ -10,10 +10,10 @@ use std::iter::Iterator;
|
|||
|
||||
#[derive(Clone, Debug, Eq)]
|
||||
pub struct Board {
|
||||
flags: Flags,
|
||||
pieces: PieceSet,
|
||||
en_passant: Option<EnPassant>,
|
||||
pub move_counter: MoveCounter,
|
||||
pub castling_rights: castle::Rights,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
|
@ -91,6 +91,39 @@ impl Board {
|
|||
self.piece_on_square(square)
|
||||
}
|
||||
|
||||
/// Returns `true` if the player is able to castle on the given side of the board.
|
||||
///
|
||||
/// The following requirements must be met:
|
||||
///
|
||||
/// 1. The player must still have the right to castle on that side of the
|
||||
/// board. The king and rook involved in the castle must not have moved.
|
||||
/// 1. The spaces between the king and rook must be clear
|
||||
/// 2. The king must not be in check
|
||||
/// 3. In the course of castling on that side, the king must not pass
|
||||
/// through a square that an enemy piece can see
|
||||
pub fn player_can_castle(&self, player: Color, castle: Castle) -> bool {
|
||||
if !self
|
||||
.castling_rights
|
||||
.player_has_right_to_castle(player, castle.into())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let castling_parameters = castle.parameters(player);
|
||||
|
||||
let all_pieces = self.all_pieces_bitboard();
|
||||
if !(all_pieces & castling_parameters.clear_squares()).is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let danger_squares = self.king_danger(player);
|
||||
if !(danger_squares & castling_parameters.check_squares()).is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// A [`BitBoard`] representing the set of squares containing a piece. This
|
||||
/// set is the inverse of [`Board::empty_squares`].
|
||||
#[must_use]
|
||||
|
@ -182,7 +215,7 @@ impl Board {
|
|||
impl Default for Board {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
flags: Flags::default(),
|
||||
castling_rights: castle::Rights::default(),
|
||||
pieces: PieceSet::default(),
|
||||
en_passant: None,
|
||||
move_counter: MoveCounter::default(),
|
||||
|
@ -193,7 +226,7 @@ impl Default for Board {
|
|||
impl PartialEq for Board {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.pieces == other.pieces
|
||||
&& self.flags == other.flags
|
||||
&& self.castling_rights == other.castling_rights
|
||||
&& self.en_passant == other.en_passant
|
||||
&& self.move_counter == other.move_counter
|
||||
}
|
||||
|
@ -232,8 +265,12 @@ mod tests {
|
|||
#[test]
|
||||
fn king_not_on_starting_square_cannot_castle() {
|
||||
let board = test_board!(White King on E4);
|
||||
assert!(!board.player_has_right_to_castle(Color::White, Castle::KingSide));
|
||||
assert!(!board.player_has_right_to_castle(Color::White, Castle::QueenSide));
|
||||
assert!(!board
|
||||
.castling_rights
|
||||
.player_has_right_to_castle(Color::White, Castle::KingSide));
|
||||
assert!(!board
|
||||
.castling_rights
|
||||
.player_has_right_to_castle(Color::White, Castle::QueenSide));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -244,8 +281,12 @@ mod tests {
|
|||
White Rook on H1
|
||||
);
|
||||
|
||||
assert!(board.player_has_right_to_castle(Color::White, Castle::KingSide));
|
||||
assert!(board.player_has_right_to_castle(Color::White, Castle::QueenSide));
|
||||
assert!(board
|
||||
.castling_rights
|
||||
.player_has_right_to_castle(Color::White, Castle::KingSide));
|
||||
assert!(board
|
||||
.castling_rights
|
||||
.player_has_right_to_castle(Color::White, Castle::QueenSide));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::{piece_sets::Mailbox, Board, Castle, EnPassant, Flags, MoveCounter, PieceSet};
|
||||
use crate::{castle, piece_sets::Mailbox, Board, Castle, EnPassant, MoveCounter, PieceSet};
|
||||
use chessfriend_core::{piece, Color, PlacedPiece, Rank, Shape, Square};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Builder {
|
||||
flags: Flags,
|
||||
castling_rights: castle::Rights,
|
||||
pieces: Mailbox,
|
||||
kings: [Option<Square>; Color::NUM],
|
||||
en_passant: Option<EnPassant>,
|
||||
|
@ -26,8 +26,8 @@ impl Builder {
|
|||
let black_king = board.king_square(Color::Black);
|
||||
|
||||
Self {
|
||||
flags: *board.flags(),
|
||||
pieces,
|
||||
castling_rights: board.castling_rights,
|
||||
kings: [Some(white_king), Some(black_king)],
|
||||
en_passant: board.en_passant(),
|
||||
move_counter: board.move_counter,
|
||||
|
@ -74,13 +74,13 @@ impl Builder {
|
|||
}
|
||||
|
||||
pub fn player_can_castle(&mut self, color: Color, castle: Castle) -> &mut Self {
|
||||
self.flags
|
||||
self.castling_rights
|
||||
.set_player_has_right_to_castle_flag(color, castle);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn no_castling_rights(&mut self) -> &mut Self {
|
||||
self.flags.clear_all_castling_rights();
|
||||
self.castling_rights.clear_all();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ impl Builder {
|
|||
.filter(Self::is_piece_placement_valid)
|
||||
.collect();
|
||||
|
||||
let mut flags = self.flags;
|
||||
let mut castling_rights = self.castling_rights;
|
||||
|
||||
for color in Color::ALL {
|
||||
for castle in Castle::ALL {
|
||||
|
@ -105,16 +105,16 @@ impl Builder {
|
|||
self.kings[color as usize] == Some(parameters.king_origin_square());
|
||||
|
||||
if !king_is_on_starting_square || !has_rook_on_starting_square {
|
||||
flags.clear_player_has_right_to_castle_flag(color, castle);
|
||||
castling_rights.clear_player_has_right_to_castle_flag(color, castle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Board {
|
||||
flags,
|
||||
pieces,
|
||||
self.en_passant,
|
||||
move_counter: self.move_counter,
|
||||
castling_rights,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ impl Default for Builder {
|
|||
]);
|
||||
|
||||
Self {
|
||||
flags: Flags::default(),
|
||||
castling_rights: castle::Rights::default(),
|
||||
pieces,
|
||||
kings: [Some(white_king_square), Some(black_king_square)],
|
||||
en_passant: None,
|
||||
|
|
|
@ -103,8 +103,10 @@ impl ToFenStr for Board {
|
|||
(Color::Black, Castle::QueenSide),
|
||||
]
|
||||
.map(|(color, castle)| {
|
||||
let can_castle = self.player_has_right_to_castle(color, castle);
|
||||
if !can_castle {
|
||||
if !self
|
||||
.castling_rights
|
||||
.player_has_right_to_castle(color, castle)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue