You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
inkwell/src/eval.rs

99 lines
3.3 KiB

use chess::{Board, BoardStatus, ChessMove, Color, MoveGen, Piece};
pub fn eval_board(
board: Board,
playing_as: Color,
curr_depth: u8,
move_history: Vec<(ChessMove, Board)>,
) -> i128 {
let mut current_eval: i128 = 0;
let moves_iter = MoveGen::new_legal(&board).into_iter();
moves_iter.for_each(|mov| {
let tmp_board = board.make_move_new(mov);
// force it to not draw (and cockblock someone trying *to* draw)
if move_history.len() > 6 {
if move_history[move_history.len() - 2].0 == mov
&& move_history[move_history.len() - 6].0 == mov
{
current_eval -= 6666666666666666666666666666;
return;
}
}
// basic material counting
tmp_board.color_combined(playing_as).for_each(|square| {
match tmp_board.piece_on(square) {
Some(Piece::Pawn) => current_eval += 1,
Some(Piece::Knight) => current_eval += 3,
Some(Piece::Bishop) => current_eval += 5,
Some(Piece::Rook) => current_eval += 5,
Some(Piece::Queen) => current_eval += 8,
_ => { /* do nothing */ }
}
});
tmp_board.color_combined(!playing_as).for_each(|square| {
match tmp_board.piece_on(square) {
Some(Piece::Pawn) => current_eval -= 1,
Some(Piece::Knight) => current_eval -= 3,
Some(Piece::Bishop) => current_eval -= 5,
Some(Piece::Rook) => current_eval -= 5,
Some(Piece::Queen) => current_eval -= 8,
_ => { /* do nothing */ }
}
});
// checking heuristic
let mut are_we_in_check = false;
let mut is_opponent_in_check = false;
tmp_board
.checkers()
.filter(|sq| tmp_board.color_on(*sq).unwrap() == playing_as)
.for_each(|_| {
if !are_we_in_check {
current_eval -= 666;
are_we_in_check = true;
} else {
current_eval -= 15;
}
});
tmp_board
.checkers()
.filter(|sq| tmp_board.color_on(*sq).unwrap() == !playing_as)
.for_each(|_| {
if !is_opponent_in_check {
current_eval += 15;
is_opponent_in_check = true;
} else {
current_eval += 5;
}
});
// die
if tmp_board.status() == BoardStatus::Checkmate && tmp_board.side_to_move() == playing_as {
current_eval -= 666_666;
}
// go for checkmate
if tmp_board.status() == BoardStatus::Checkmate && tmp_board.side_to_move() == !playing_as {
current_eval += 666_666;
}
// deprioritize king movement
if board.piece_on(mov.get_source()).unwrap() == Piece::King && !are_we_in_check {
current_eval -= 10;
}
if curr_depth != 0 {
let mut new_move_history = move_history.clone();
new_move_history.push((mov, tmp_board));
current_eval += eval_board(tmp_board, playing_as, curr_depth - 1, new_move_history);
}
});
return current_eval;
}