use crate::board::Board;
use crate::types::{Color, PieceType};
use super::attackers::get_attackers;
use super::defenders::get_defenders;
use super::types::BoardPiece;
pub fn is_piece_safe(board: &Board, piece: &BoardPiece) -> bool {
let attacker_color = piece.piece.color.opposite();
let direct_attackers = super::attackers::get_direct_attackers(
board, piece.square, attacker_color,
);
let attackers = get_attackers(board, piece.square, attacker_color);
let defenders = get_defenders(board, piece, true);
let has_lower_value_attacker = direct_attackers.iter().any(|attacker| {
attacker.piece.piece_type.value() < piece.piece.piece_type.value()
});
if has_lower_value_attacker {
return false;
}
if attackers.len() <= defenders.len() {
return true;
}
let lowest_attacker_value = direct_attackers
.iter()
.map(|a| a.piece.piece_type.value())
.min();
if let Some(lav) = lowest_attacker_value
&& piece.piece.piece_type.value() < lav
&& defenders.iter().any(|d| d.piece.piece_type.value() < lav)
{
return true;
}
if defenders.iter().any(|d| d.piece.piece_type == PieceType::Pawn) {
return true;
}
false
}
pub fn get_unsafe_pieces(
board: &Board,
color: Color,
last_move_captured_value: Option<i32>,
) -> Vec<BoardPiece> {
let captured_value = last_move_captured_value.unwrap_or(0);
board
.squares()
.into_iter()
.enumerate()
.filter_map(|(sq, cell)| {
let piece = cell.filter(|p| {
p.color == color
&& p.piece_type != PieceType::Pawn
&& p.piece_type != PieceType::King
&& p.piece_type.value() > captured_value
})?;
Some(BoardPiece::new(piece, sq as u8))
})
.filter(|bp| !is_piece_safe(board, bp))
.collect()
}