use crate::board::Board;
use super::brilliant::is_critical_candidate;
use super::expected_points::get_expected_points_loss;
use super::piece_safety::is_piece_safe;
use super::types::{BoardPiece, ClassificationContext};
use crate::Piece;
const GREAT_SECOND_MOVE_THRESHOLD: f64 = 0.10;
pub fn is_great(
board_before: &Board,
ctx: &ClassificationContext,
) -> bool {
if !is_critical_candidate(ctx) {
return false;
}
if let Some(captured_type) = board_before.piece_at(ctx.played_move.to).map(|p| p.piece_type) {
let captured_piece = BoardPiece::new(
Piece::new(captured_type, ctx.color),
ctx.played_move.to,
);
if !is_piece_safe(board_before, &captured_piece) {
return false;
}
}
let second_eval = match ctx.second_best_eval {
Some(e) => e,
None => return false,
};
let second_loss = get_expected_points_loss(ctx.eval_before, second_eval, ctx.color);
second_loss >= GREAT_SECOND_MOVE_THRESHOLD
}