Refactor project structure to use submodules
This commit is contained in:
116
src/evaluation/evaluation.rs
Normal file
116
src/evaluation/evaluation.rs
Normal file
@@ -0,0 +1,116 @@
|
||||
use u64 as Bitboard;
|
||||
|
||||
use crate::{
|
||||
board::bitboard::lsb,
|
||||
board::board::{Board, Color, PieceType},
|
||||
evaluation::psqt::{mirror_index, piece_square_score},
|
||||
};
|
||||
|
||||
const fn piece_score(piece_type: PieceType) -> i32 {
|
||||
match piece_type {
|
||||
PieceType::Pawn => 100,
|
||||
PieceType::Knight => 320,
|
||||
PieceType::Bishop => 330,
|
||||
PieceType::Rook => 500,
|
||||
PieceType::Queen => 900,
|
||||
PieceType::King => 20000,
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_side(board: &Board, color: Color) -> i32 {
|
||||
let mut total_score = 0;
|
||||
let pieces = match color {
|
||||
Color::White => &board.white_pieces,
|
||||
Color::Black => &board.black_pieces,
|
||||
};
|
||||
|
||||
for piece in pieces {
|
||||
let (piece_type, mut bitboard): (PieceType, Bitboard) = (piece.piece_type, piece.bitboard);
|
||||
let mut score = 0;
|
||||
while bitboard != 0 {
|
||||
let psqt_index = match color {
|
||||
Color::White => lsb(bitboard),
|
||||
Color::Black => mirror_index(lsb(bitboard)),
|
||||
};
|
||||
|
||||
score += piece_score(piece_type);
|
||||
score += piece_square_score(piece_type, psqt_index);
|
||||
bitboard &= bitboard - 1;
|
||||
}
|
||||
total_score += score;
|
||||
}
|
||||
total_score
|
||||
}
|
||||
|
||||
pub fn evaluate_position(board: &Board, color: Color) -> i32 {
|
||||
let total_white_score = evaluate_side(board, Color::White);
|
||||
let total_black_score = evaluate_side(board, Color::Black);
|
||||
let evaluation = total_white_score - total_black_score;
|
||||
|
||||
match color {
|
||||
Color::White => evaluation,
|
||||
Color::Black => -evaluation,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
board::board::{Color, PieceType},
|
||||
board::fen::from_fen,
|
||||
evaluation::evaluation::{evaluate_position, evaluate_side, piece_score},
|
||||
};
|
||||
|
||||
const FEN_QUIET: [&str; 2] = [
|
||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||
"rnbqkbnr/ppp2ppp/4p3/3pN3/3P4/8/PPP1PPPP/RNBQKB1R w KQkq - 0 1",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_piece_score() -> Result<(), String> {
|
||||
assert_eq!(100, piece_score(PieceType::Pawn));
|
||||
assert_eq!(320, piece_score(PieceType::Knight));
|
||||
assert_eq!(330, piece_score(PieceType::Bishop));
|
||||
assert_eq!(500, piece_score(PieceType::Rook));
|
||||
assert_eq!(900, piece_score(PieceType::Queen));
|
||||
assert_eq!(20000, piece_score(PieceType::King));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_evaluate_side() -> Result<(), String> {
|
||||
let game = from_fen(FEN_QUIET[0])?;
|
||||
|
||||
assert_eq!(
|
||||
evaluate_side(&game.board, Color::White),
|
||||
evaluate_side(&game.board, Color::Black)
|
||||
);
|
||||
|
||||
let game_2 = from_fen(FEN_QUIET[1])?;
|
||||
let evaluate_white = evaluate_side(&game_2.board, Color::White);
|
||||
let evaluate_black = evaluate_side(&game_2.board, Color::Black);
|
||||
|
||||
assert_eq!(24005, evaluate_white);
|
||||
assert_eq!(23965, evaluate_black);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_evaluate() -> Result<(), String> {
|
||||
let game = from_fen(FEN_QUIET[0])?;
|
||||
|
||||
assert_eq!(
|
||||
evaluate_position(&game.board, Color::White),
|
||||
evaluate_position(&game.board, Color::Black)
|
||||
);
|
||||
|
||||
let game_2 = from_fen(FEN_QUIET[1])?;
|
||||
|
||||
assert_eq!(40, evaluate_position(&game_2.board, Color::White));
|
||||
assert_eq!(-40, evaluate_position(&game_2.board, Color::Black));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user