use crate::position::Position; use crate::types::{PieceType, Color}; use crate::bitboard::{pop_lsb, EMPTY}; const MG_WEIGHTS: [i32; 7] = [0, 82, 337, 365, 477, 1025, 20000]; const PAWN_PST: [i32; 64] = [ 0, 0, 0, 0, 0, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 50, 10, 10, 20, 30, 30, 20, 10, 10, 5, 5, 10, 25, 25, 10, 5, 5, 0, 0, 0, 20, 20, 0, 0, 0, 5, -5,-10, 0, 0,-10, -5, 5, 5, 10, 10,-20,-20, 10, 10, 5, 0, 0, 0, 0, 0, 0, 0, 0 ]; const KNIGHT_PST: [i32; 64] = [ -50,-40,-30,-30,-30,-30,-40,-50, -40,-20, 0, 0, 0, 0,-20,-40, -30, 0, 10, 15, 15, 10, 0,-30, -30, 5, 15, 20, 20, 15, 5,-30, -30, 0, 15, 20, 20, 15, 0,-30, -30, 5, 10, 15, 15, 10, 5,-30, -40,-20, 0, 5, 5, 0,-20,-40, -50,-40,-30,-30,-30,-30,-40,-50 ]; const BISHOP_PST: [i32; 64] = [ -20,-10,-10,-10,-10,-10,-10,-20, -10, 0, 0, 0, 0, 0, 0,-10, -10, 0, 5, 10, 10, 5, 0,-10, -10, 5, 5, 10, 10, 5, 5,-10, -10, 0, 10, 10, 10, 10, 0,-10, -10, 10, 10, 10, 10, 10, 10,-10, -10, 5, 0, 0, 0, 0, 5,-10, -20,-10,-10,-10,-10,-10,-10,-20 ]; const ROOK_PST: [i32; 64] = [ 0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 10, 10, 10, 10, 10, 5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, -5, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 5, 5, 0, 0, 0 ]; const QUEEN_PST: [i32; 64] = [ -20,-10,-10, -5, -5,-10,-10,-20, -10, 0, 0, 0, 0, 0, 0,-10, -10, 0, 5, 5, 5, 5, 0,-10, -5, 0, 5, 5, 5, 5, 0, -5, 0, 0, 5, 5, 5, 5, 0, -5, -10, 5, 5, 5, 5, 5, 0,-10, -10, 0, 5, 0, 0, 0, 0,-10, -20,-10,-10, -5, -5,-10,-10,-20 ]; const KING_MG_PST: [i32; 64] = [ -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -20,-30,-30,-40,-40,-30,-30,-20, -10,-20,-20,-20,-20,-20,-20,-10, 20, 20, 0, 0, 0, 0, 20, 20, 20, 30, 10, 0, 0, 10, 30, 20 ]; fn mirror_sq(sq: usize) -> usize { sq ^ 56 } fn get_pst_score(p_type: PieceType, sq: usize, is_white: bool) -> i32 { let index = if is_white { mirror_sq(sq) } else { sq }; match p_type { PieceType::Pawn => PAWN_PST[index], PieceType::Knight => KNIGHT_PST[index], PieceType::Bishop => BISHOP_PST[index], PieceType::Rook => ROOK_PST[index], PieceType::Queen => QUEEN_PST[index], PieceType::King => KING_MG_PST[index], _ => 0, } } pub fn evaluate(pos: &Position) -> i32 { let mut score = 0; for p in 1..=6 { let p_type: PieceType = unsafe { std::mem::transmute(p as u8) }; let mut w_pieces = pos.pieces[p] & pos.colors[Color::White as usize]; while w_pieces != EMPTY { let sq = pop_lsb(&mut w_pieces) as usize; score += MG_WEIGHTS[p]; score += get_pst_score(p_type, sq, true); } let mut b_pieces = pos.pieces[p] & pos.colors[Color::Black as usize]; while b_pieces != EMPTY { let sq = pop_lsb(&mut b_pieces) as usize; score -= MG_WEIGHTS[p]; score -= get_pst_score(p_type, sq, false); } } if pos.side_to_move == Color::White { score } else { -score } }