63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
|
// Eryn Wells <eryn@erynwells.me>
|
||
|
|
||
|
use chessfriend_board::Board;
|
||
|
use chessfriend_core::{Color, Piece, Shape, score::Score};
|
||
|
|
||
|
struct Evaluator;
|
||
|
|
||
|
impl Evaluator {
|
||
|
pub fn evaluate_symmetric_unwrapped(board: &Board, color: Color) -> Score {
|
||
|
let material_balance = Self::material_balance(board, color);
|
||
|
|
||
|
let to_move_factor = color.score_factor();
|
||
|
|
||
|
to_move_factor * material_balance
|
||
|
}
|
||
|
|
||
|
/// Evaluate a board using the symmetric evaluation algorithm defined by
|
||
|
/// Claude Shannon.
|
||
|
fn material_balance(board: &Board, color: Color) -> Score {
|
||
|
let other_color = color.other();
|
||
|
|
||
|
Shape::into_iter().fold(Score::zero(), |acc, shape| {
|
||
|
let (active_pieces, other_pieces) = (
|
||
|
board.count_piece(&Piece::new(color, shape)) as i32,
|
||
|
board.count_piece(&Piece::new(other_color, shape)) as i32,
|
||
|
);
|
||
|
|
||
|
let factor = shape.score() * (active_pieces - other_pieces);
|
||
|
|
||
|
acc + factor
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use super::*;
|
||
|
use chessfriend_board::fen;
|
||
|
|
||
|
#[test]
|
||
|
fn pawn_material_balance() -> Result<(), Box<dyn std::error::Error>> {
|
||
|
let board = fen!("8/8/8/8/8/3P4/8/8 w - - 0 1")?;
|
||
|
assert_eq!(
|
||
|
Evaluator::material_balance(&board, Color::White),
|
||
|
100i32.into()
|
||
|
);
|
||
|
|
||
|
let board = fen!("8/8/3p4/8/8/3P4/8/8 w - - 0 1")?;
|
||
|
assert_eq!(Evaluator::material_balance(&board, Color::White), 0.into());
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn starting_position_is_even() {
|
||
|
let board = Board::starting(None);
|
||
|
assert_eq!(
|
||
|
Evaluator::evaluate_symmetric_unwrapped(&board, Color::White),
|
||
|
Evaluator::evaluate_symmetric_unwrapped(&board, Color::Black)
|
||
|
);
|
||
|
}
|
||
|
}
|