[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