[board] Implement Position::is_king_in_check()
Returns true if the king of the current player is in check.
This commit is contained in:
parent
81d544f0d5
commit
96b04379a4
1 changed files with 44 additions and 1 deletions
|
@ -4,8 +4,10 @@ use super::{flags::Flags, Pieces};
|
|||
use crate::{
|
||||
moves::Moves,
|
||||
piece::{Color, Piece, PiecePlacementError, PlacedPiece, Shape},
|
||||
sight::Sight,
|
||||
BitBoard, Square,
|
||||
};
|
||||
use std::cell::OnceCell;
|
||||
use std::fmt;
|
||||
use std::fmt::Write;
|
||||
|
||||
|
@ -26,7 +28,7 @@ macro_rules! position {
|
|||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct Position {
|
||||
color_to_move: Color,
|
||||
|
||||
|
@ -46,6 +48,8 @@ pub struct Position {
|
|||
pieces_per_type: [[BitBoard; 6]; 2],
|
||||
|
||||
en_passant_square: Option<Square>,
|
||||
|
||||
sight: [OnceCell<BitBoard>; 2],
|
||||
}
|
||||
|
||||
impl Position {
|
||||
|
@ -73,6 +77,7 @@ impl Position {
|
|||
],
|
||||
],
|
||||
en_passant_square: None,
|
||||
sight: [OnceCell::new(), OnceCell::new()],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,6 +110,7 @@ impl Position {
|
|||
],
|
||||
pieces_per_type: [white_pieces, black_pieces],
|
||||
en_passant_square: None,
|
||||
sight: [OnceCell::new(), OnceCell::new()],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,6 +219,25 @@ impl Position {
|
|||
pub fn en_passant_square(&self) -> Option<Square> {
|
||||
self.en_passant_square
|
||||
}
|
||||
|
||||
pub(crate) fn sight_of_player(&self, color: Color) -> BitBoard {
|
||||
*self.sight[color as usize].get_or_init(|| {
|
||||
self.pieces(color).fold(BitBoard::empty(), |acc, pp| {
|
||||
acc | pp.sight_in_position(&self)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn is_king_in_check(&self) -> bool {
|
||||
let sight_of_opposing_player = self.sight_of_player(self.color_to_move.other());
|
||||
let king_square = self
|
||||
.bitboard_for_piece(Piece::king(self.color_to_move))
|
||||
.occupied_squares()
|
||||
.next()
|
||||
.unwrap();
|
||||
sight_of_opposing_player.is_set(king_square)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Position {
|
||||
|
@ -288,4 +313,22 @@ mod tests {
|
|||
.place_piece(piece, square)
|
||||
.expect_err("Placed white queen on e4 a second time?!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn king_is_in_check() {
|
||||
let pos = position![
|
||||
White King on E1,
|
||||
Black Rook on E8,
|
||||
];
|
||||
assert!(pos.is_king_in_check());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn king_is_not_in_check() {
|
||||
let pos = position![
|
||||
White King on F1,
|
||||
Black Rook on E8,
|
||||
];
|
||||
assert!(!pos.is_king_in_check());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue