diff --git a/board/src/movement.rs b/board/src/movement.rs index 8cb8be9..2935eee 100644 --- a/board/src/movement.rs +++ b/board/src/movement.rs @@ -4,12 +4,12 @@ //! of squares a piece can move to. For all pieces except pawns, the Movement //! set is equal to the Sight set. -use crate::{sight::Sight, Board}; +use crate::{Board, sight::Sight}; use chessfriend_bitboard::BitBoard; use chessfriend_core::{Color, Piece, Rank, Shape, Square, Wing}; impl Board { - pub fn movement(&self, square: Square) -> BitBoard { + pub fn movement_piece(&self, square: Square) -> BitBoard { if let Some(piece) = self.get_piece(square) { piece.movement(square, self) } else { @@ -93,7 +93,7 @@ fn pawn_pushes(pawn: BitBoard, color: Color, occupancy: BitBoard) -> BitBoard { #[cfg(test)] mod tests { use super::pawn_pushes; - use chessfriend_bitboard::{bitboard, BitBoard}; + use chessfriend_bitboard::{BitBoard, bitboard}; use chessfriend_core::{Color, Square}; #[test] diff --git a/board/src/sight.rs b/board/src/sight.rs index f6378b2..8e5cbc6 100644 --- a/board/src/sight.rs +++ b/board/src/sight.rs @@ -23,7 +23,7 @@ use std::ops::BitOr; impl Board { /// Compute sight of the piece on the given square. - pub fn sight(&self, square: Square) -> BitBoard { + pub fn sight_piece(&self, square: Square) -> BitBoard { if let Some(piece) = self.get_piece(square) { piece.sight(square, self) } else { @@ -31,8 +31,23 @@ impl Board { } } - pub fn active_sight(&self) -> BitBoard { - self.friendly_sight(self.active_color()) + /// Calculate sight of all pieces of the given [`Color`]. If `color` is + /// `None`, calculate sight of the active color. + pub fn sight(&self, color: Option) -> BitBoard { + self.sight_unwrapped(self.unwrap_color(color)) + } + + /// Calculate sight of all pieces of the active color. + pub fn sight_active(&self) -> BitBoard { + self.sight_unwrapped(self.active_color()) + } + + /// Calculate sight of all pieces of the given [`Color`]. + pub fn sight_unwrapped(&self, color: Color) -> BitBoard { + self.friendly_occupancy(color) + .occupied_squares_leading() + .map(|square| self.sight_piece(square)) + .fold(BitBoard::EMPTY, BitOr::bitor) } /// A [`BitBoard`] of all squares the given color can see. @@ -40,7 +55,7 @@ impl Board { // TODO: Probably want to implement a caching layer here. self.friendly_occupancy(color) .occupied_squares(&IterationDirection::default()) - .map(|square| self.sight(square)) + .map(|square| self.sight_piece(square)) .fold(BitBoard::EMPTY, BitOr::bitor) } @@ -244,7 +259,7 @@ mod tests { White King on E4, ); - let sight = pos.active_sight(); + let sight = pos.sight_active(); assert_eq!(sight, bitboard![E5 F5 F4 F3 E3 D3 D4 D5]); } @@ -267,8 +282,8 @@ mod tests { mod pawn { use crate::{sight::Sight, test_board}; - use chessfriend_bitboard::{bitboard, BitBoard}; - use chessfriend_core::{piece, Square}; + use chessfriend_bitboard::{BitBoard, bitboard}; + use chessfriend_core::{Square, piece}; sight_test!(e4_pawn, piece!(White Pawn), Square::E4, bitboard![D5 F5]); diff --git a/explorer/src/main.rs b/explorer/src/main.rs index b6af7a6..cfaf102 100644 --- a/explorer/src/main.rs +++ b/explorer/src/main.rs @@ -65,7 +65,7 @@ fn command_line() -> Command { ) .subcommand( Command::new("sight") - .arg(Arg::new("square").required(true)) + .arg(Arg::new("square").required(false)) .about("Show sight of a piece on a square"), ) .subcommand( @@ -163,12 +163,12 @@ fn respond(line: &str, state: &mut State) -> anyhow::Result { .place_piece(piece, square, PlacePieceStrategy::default())?; } Some(("sight", matches)) => { - let square = matches - .get_one::("square") - .ok_or(CommandHandlingError::MissingArgument("square"))?; - let square = square.parse::()?; - - let sight = state.position.sight(square); + let sight = if let Some(square) = matches.get_one::("square") { + let square: Square = square.parse()?; + state.position.sight_piece(square) + } else { + state.position.sight_active() + }; let display = state.position.display().highlight(sight); println!("\n{display}"); @@ -331,7 +331,7 @@ fn do_movement_command( .get_one::("square") .ok_or(CommandHandlingError::MissingArgument("square"))?; - let movement = state.position.movement(square); + let movement = state.position.movement_piece(square); let display = state.position.display().highlight(movement); println!("\n{display}"); diff --git a/position/src/position.rs b/position/src/position.rs index 5a3ae69..d2a82f3 100644 --- a/position/src/position.rs +++ b/position/src/position.rs @@ -86,12 +86,14 @@ impl Position { } impl Position { - pub fn sight(&self, square: Square) -> BitBoard { - self.board.sight(square) + /// Calculate sight of a piece on the provided [`Square`]. + pub fn sight_piece(&self, square: Square) -> BitBoard { + self.board.sight_piece(square) } - pub fn movement(&self, square: Square) -> BitBoard { - self.board.movement(square) + /// Calculate movement of a piece on the provided [`Square`]. + pub fn movement_piece(&self, square: Square) -> BitBoard { + self.board.movement_piece(square) } } @@ -163,8 +165,8 @@ impl Position { } impl Position { - pub fn active_sight(&self) -> BitBoard { - self.board.active_sight() + pub fn sight_active(&self) -> BitBoard { + self.board.sight_active() } /// A [`BitBoard`] of all squares the given color can see. @@ -285,7 +287,7 @@ impl Position { } let target_bitboard: BitBoard = target.into(); - if !(self.movement(origin) & target_bitboard).is_populated() { + if !(self.movement_piece(origin) & target_bitboard).is_populated() { return None; }