From b69323665c983950473190873f2cc92cd65db14d Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 18 Nov 2025 20:14:47 +0100 Subject: [PATCH] integrated material eval into psqt --- progress_tracking/progress.xlsx | Bin 10327 -> 5908 bytes src/bin/suite.rs | 4 +- src/eval/basic.rs | 109 ++++++++++++-------------- src/eval/piece_square_tables.rs | 134 ++++++++++++++++++-------------- 4 files changed, 127 insertions(+), 120 deletions(-) diff --git a/progress_tracking/progress.xlsx b/progress_tracking/progress.xlsx index 9332089ab2a82a55d3f53d35b2f35aaa57da5e45..25d9b61b2f581143d38df5b4817a2ff68ea02de3 100644 GIT binary patch literal 5908 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 literal 10327 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 O{GkEEn2`GC+5Z9IC)O|k diff --git a/src/bin/suite.rs b/src/bin/suite.rs index 5b4d8e5..997acab 100644 --- a/src/bin/suite.rs +++ b/src/bin/suite.rs @@ -29,7 +29,7 @@ fn main() { let mut engine = Engine::new("Yakari".to_string(), "EiSiMo".to_string()); // Set the time limit to 1 second - let time_limit = Duration::from_millis(500); + let time_limit = Duration::from_millis(1000); for test in &sts { let fen = &test[0]; @@ -40,7 +40,7 @@ fn main() { // Record start time let start_time = Instant::now(); - let result = engine.search(490_u64); + let result = engine.search(990_u64); // Calculate duration let duration = start_time.elapsed(); diff --git a/src/eval/basic.rs b/src/eval/basic.rs index 1ecd734..a02dac1 100644 --- a/src/eval/basic.rs +++ b/src/eval/basic.rs @@ -1,74 +1,67 @@ use crate::board::*; use crate::eval::piece_square_tables::PSQT; -// Pawn, Knight, Bishop, Rook, Queen -pub const MATERIAL_WEIGHTS: [i32; 5] = [100, 300, 300, 500, 900]; -pub const PHASE_WEIGHTS: [i32; 5] = [0, 1, 1, 2, 4]; - pub fn evaluate_board(board: &Board) -> i32 { let mut mg_score = 0_i32; let mut eg_score = 0_i32; let mut phase = 0_i32; - // --- WHITE PIECES --- - // Iterating Pawn (0) to Queen (4) for Material + Phase + PSQT - for pt in 0..5 { - let mut pieces = board.pieces[pt][Color::White as usize]; - let count = pieces.count_ones() as i32; - - mg_score += count * MATERIAL_WEIGHTS[pt]; - eg_score += count * MATERIAL_WEIGHTS[pt]; - phase += count * PHASE_WEIGHTS[pt]; + // We use a macro to force loop unrolling. + // This enables the compiler to use constant offsets for PSQT access + // instead of calculating addresses at runtime based on a loop variable. + macro_rules! score_piece { + ($pt:expr, $phase_weight:expr) => { + // --- WHITE --- + let mut pieces = board.pieces[$pt][Color::White as usize]; + if pieces > 0 { + // Phase calculation uses count_ones (POPPCNT) which is very fast + phase += (pieces.count_ones() as i32) * $phase_weight; - while pieces > 0 { - let sq = pieces.trailing_zeros() as usize; - pieces &= pieces - 1; // Clear LS1B - - // Access: [Piece][Color][Phase (0=MG, 1=EG)][Square] - mg_score += PSQT[pt][Color::White as usize][0][sq]; - eg_score += PSQT[pt][Color::White as usize][1][sq]; - } + while pieces > 0 { + let sq = pieces.trailing_zeros() as usize; + pieces &= pieces - 1; // Clear LS1B + + // Material is already baked into PSQT, so we just add the table value + // Since $pt is a const literal here, this compiles to a direct memory access + mg_score += PSQT[$pt][Color::White as usize][0][sq]; + eg_score += PSQT[$pt][Color::White as usize][1][sq]; + } + } + + // --- BLACK --- + let mut pieces = board.pieces[$pt][Color::Black as usize]; + if pieces > 0 { + phase += (pieces.count_ones() as i32) * $phase_weight; + + while pieces > 0 { + let sq = pieces.trailing_zeros() as usize; + pieces &= pieces - 1; + + mg_score -= PSQT[$pt][Color::Black as usize][0][sq]; + eg_score -= PSQT[$pt][Color::Black as usize][1][sq]; + } + } + }; } - // King (Index 5) - No Material/Phase weight, only PSQT - let mut white_king = board.pieces[5][Color::White as usize]; - if white_king > 0 { - let sq = white_king.trailing_zeros() as usize; - mg_score += PSQT[5][Color::White as usize][0][sq]; - eg_score += PSQT[5][Color::White as usize][1][sq]; - } + // Explicitly unrolled execution order + // Pawn (0), Weight 0 + score_piece!(0, 0); + // Knight (1), Weight 1 + score_piece!(1, 1); + // Bishop (2), Weight 1 + score_piece!(2, 1); + // Rook (3), Weight 2 + score_piece!(3, 2); + // Queen (4), Weight 4 + score_piece!(4, 4); + // King (5), Weight 0 (Phase doesn't change) + score_piece!(5, 0); - // --- BLACK PIECES --- - // Iterating Pawn (0) to Queen (4) - for pt in 0..5 { - let mut pieces = board.pieces[pt][Color::Black as usize]; - let count = pieces.count_ones() as i32; - - mg_score -= count * MATERIAL_WEIGHTS[pt]; - eg_score -= count * MATERIAL_WEIGHTS[pt]; - phase += count * PHASE_WEIGHTS[pt]; - - while pieces > 0 { - let sq = pieces.trailing_zeros() as usize; - pieces &= pieces - 1; - - mg_score -= PSQT[pt][Color::Black as usize][0][sq]; - eg_score -= PSQT[pt][Color::Black as usize][1][sq]; - } - } - - // King (Index 5) for Black - let mut black_king = board.pieces[5][Color::Black as usize]; - if black_king > 0 { - let sq = black_king.trailing_zeros() as usize; - mg_score -= PSQT[5][Color::Black as usize][0][sq]; - eg_score -= PSQT[5][Color::Black as usize][1][sq]; - } - - // Tapered Evaluation Interpolation - let phase = phase.min(24); // Clamp to 24 max + // Tapered Evaluation + let phase = phase.min(24); let mg_phase = phase; let eg_phase = 24 - phase; ((mg_score * mg_phase) + (eg_score * eg_phase)) / 24 -} +} \ No newline at end of file diff --git a/src/eval/piece_square_tables.rs b/src/eval/piece_square_tables.rs index d882e4e..18d1ca7 100644 --- a/src/eval/piece_square_tables.rs +++ b/src/eval/piece_square_tables.rs @@ -1,33 +1,47 @@ +// --- Material Values (PeSTO Standard) --- +const MG_PAWN_VAL: i32 = 82; +const EG_PAWN_VAL: i32 = 94; +const MG_KNIGHT_VAL: i32 = 337; +const EG_KNIGHT_VAL: i32 = 281; +const MG_BISHOP_VAL: i32 = 365; +const EG_BISHOP_VAL: i32 = 297; +const MG_ROOK_VAL: i32 = 477; +const EG_ROOK_VAL: i32 = 512; +const MG_QUEEN_VAL: i32 = 1025; +const EG_QUEEN_VAL: i32 = 936; +const MG_KING_VAL: i32 = 0; // King usually has no material value in eval summation (captured = game over) +const EG_KING_VAL: i32 = 0; + pub const MG_PAWN_TABLE: [i32; 64] = [ - 0, 0, 0, 0, 0, 0, 0, 0, - 98, 134, 61, 95, 68, 126, 34, -11, - -6, 7, 26, 31, 65, 56, 25, -20, + 0, 0, 0, 0, 0, 0, 0, 0, + 98, 134, 61, 95, 68, 126, 34, -11, + -6, 7, 26, 31, 65, 56, 25, -20, -14, 13, 6, 21, 23, 12, 17, -23, -27, -2, -5, 12, 17, 6, 10, -25, -26, -4, -4, -10, 3, 3, 33, -12, -35, -1, -20, -23, -15, 24, 38, -22, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, ]; pub const EG_PAWN_TABLE: [i32; 64] = [ - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 178, 173, 158, 134, 147, 132, 165, 187, - 94, 100, 85, 67, 56, 53, 82, 84, - 32, 24, 13, 5, -2, 4, 17, 17, - 13, 9, -3, -7, -7, -8, 3, -1, - 4, 7, -6, 1, 0, -5, -1, -8, - 13, 8, 8, 10, 13, 0, 2, -7, - 0, 0, 0, 0, 0, 0, 0, 0, + 94, 100, 85, 67, 56, 53, 82, 84, + 32, 24, 13, 5, -2, 4, 17, 17, + 13, 9, -3, -7, -7, -8, 3, -1, + 4, 7, -6, 1, 0, -5, -1, -8, + 13, 8, 8, 10, 13, 0, 2, -7, + 0, 0, 0, 0, 0, 0, 0, 0, ]; pub const MG_KNIGHT_TABLE: [i32; 64] = [ -167, -89, -34, -49, 61, -97, -15, -107, - -73, -41, 72, 36, 23, 62, 7, -17, - -47, 60, 37, 65, 84, 129, 73, 44, - -9, 17, 19, 53, 37, 69, 18, 22, - -13, 4, 16, 13, 28, 19, 21, -8, - -23, -9, 12, 10, 19, 17, 25, -16, - -29, -53, -12, -3, -1, 18, -14, -19, + -73, -41, 72, 36, 23, 62, 7, -17, + -47, 60, 37, 65, 84, 129, 73, 44, + -9, 17, 19, 53, 37, 69, 18, 22, + -13, 4, 16, 13, 28, 19, 21, -8, + -23, -9, 12, 10, 19, 17, 25, -16, + -29, -53, -12, -3, -1, 18, -14, -19, -105, -21, -58, -33, -17, -28, -19, -23, ]; @@ -46,28 +60,28 @@ pub const MG_BISHOP_TABLE: [i32; 64] = [ -29, 4, -82, -37, -25, -42, 7, -8, -26, 16, -18, -13, 30, 59, 18, -47, -16, 37, 43, 40, 35, 50, 37, -2, - -4, 5, 19, 50, 37, 37, 7, -2, - -6, 13, 13, 26, 34, 12, 10, 4, - 0, 15, 15, 15, 14, 27, 18, 10, - 4, 15, 16, 0, 7, 21, 33, 1, + -4, 5, 19, 50, 37, 37, 7, -2, + -6, 13, 13, 26, 34, 12, 10, 4, + 0, 15, 15, 15, 14, 27, 18, 10, + 4, 15, 16, 0, 7, 21, 33, 1, -33, -3, -14, -21, -13, -12, -39, -21, ]; pub const EG_BISHOP_TABLE: [i32; 64] = [ -14, -21, -11, -8, -7, -9, -17, -24, - -8, -4, 7, -12, -3, -13, -4, -14, - 2, -8, 0, -1, -2, 6, 0, 4, - -3, 9, 12, 9, 14, 10, 3, 2, - -6, 3, 13, 19, 7, 10, -3, -9, + -8, -4, 7, -12, -3, -13, -4, -14, + 2, -8, 0, -1, -2, 6, 0, 4, + -3, 9, 12, 9, 14, 10, 3, 2, + -6, 3, 13, 19, 7, 10, -3, -9, -12, -3, 8, 10, 13, 3, -7, -15, -14, -18, -7, -1, 4, -9, -15, -27, -23, -9, -23, -5, -9, -16, -5, -17, ]; pub const MG_ROOK_TABLE: [i32; 64] = [ - 32, 42, 32, 51, 63, 9, 31, 43, - 27, 32, 58, 62, 80, 67, 26, 44, - -5, 19, 26, 36, 17, 45, 61, 16, + 32, 42, 32, 51, 63, 9, 31, 43, + 27, 32, 58, 62, 80, 67, 26, 44, + -5, 19, 26, 36, 17, 45, 61, 16, -24, -11, 7, 26, 24, 35, -8, -20, -36, -26, -12, -1, 9, -7, 6, -23, -45, -25, -16, -17, 3, 0, -5, -33, @@ -78,9 +92,9 @@ pub const MG_ROOK_TABLE: [i32; 64] = [ pub const EG_ROOK_TABLE: [i32; 64] = [ 13, 10, 18, 15, 12, 12, 8, 5, 11, 13, 13, 11, -3, 3, 8, 3, - 7, 7, 7, 5, 4, -3, -5, -3, - 4, 3, 13, 1, 2, 1, -1, 2, - 3, 5, 8, 4, -5, -6, -8, -11, + 7, 7, 7, 5, 4, -3, -5, -3, + 4, 3, 13, 1, 2, 1, -1, 2, + 3, 5, 8, 4, -5, -6, -8, -11, -4, 0, -5, -1, -7, -12, -8, -16, -6, -6, 0, 2, -9, -9, -11, -3, -9, 2, 3, -1, -5, -13, 4, -20, @@ -91,17 +105,17 @@ pub const MG_QUEEN_TABLE: [i32; 64] = [ -24, -39, -5, 1, -16, 57, 28, 54, -13, -17, 7, 8, 29, 56, 47, 57, -27, -27, -16, -16, -1, 17, -2, 1, - -9, -26, -9, -10, -2, -4, 3, -3, + -9, -26, -9, -10, -2, -4, 3, -3, -14, 2, -11, -2, -5, 2, 14, 5, -35, -8, 11, 2, 8, 15, -3, 1, - -1, -18, -9, 10, -15, -25, -31, -50, + -1, -18, -9, 10, -15, -25, -31, -50, ]; pub const EG_QUEEN_TABLE: [i32; 64] = [ - -9, 22, 22, 27, 27, 19, 10, 20, + -9, 22, 22, 27, 27, 19, 10, 20, -17, 20, 32, 41, 58, 25, 30, 0, -20, 6, 9, 49, 47, 35, 19, 9, - 3, 22, 24, 45, 57, 40, 57, 36, + 3, 22, 24, 45, 57, 40, 57, 36, -18, 28, 19, 47, 31, 34, 39, 23, -16, -27, 15, 6, 9, 17, 10, 5, -22, -23, -30, -16, -16, -23, -36, -32, @@ -110,69 +124,69 @@ pub const EG_QUEEN_TABLE: [i32; 64] = [ pub const MG_KING_TABLE: [i32; 64] = [ -65, 23, 16, -15, -56, -34, 2, 13, - 29, -1, -20, -7, -8, -4, -38, -29, - -9, 24, 2, -16, -20, 6, 22, -22, + 29, -1, -20, -7, -8, -4, -38, -29, + -9, 24, 2, -16, -20, 6, 22, -22, -17, -20, -12, -27, -30, -25, -14, -36, -49, -1, -27, -39, -46, -44, -33, -51, -14, -14, -22, -46, -44, -30, -15, -27, - 1, 7, -8, -64, -43, -16, 9, 8, + 1, 7, -8, -64, -43, -16, 9, 8, -15, 36, 12, -54, 8, -28, 24, 14, ]; pub const EG_KING_TABLE: [i32; 64] = [ -74, -35, -18, -18, -11, 15, 4, -17, -12, 17, 14, 17, 17, 38, 23, 11, - 10, 17, 23, 15, 20, 45, 44, 13, - -8, 22, 24, 27, 26, 33, 26, 3, + 10, 17, 23, 15, 20, 45, 44, 13, + -8, 22, 24, 27, 26, 33, 26, 3, -18, -4, 21, 24, 27, 23, 9, -11, -19, -3, 11, 21, 23, 16, 7, -9, -27, -11, 4, 13, 14, 4, -5, -17, -53, -34, -21, -11, -28, -14, -24, -43 ]; -/// Helper function to mirror the table vertically at compile time -const fn mirror_psqt(table: [i32; 64]) -> [i32; 64] { - let mut mirrored = [0; 64]; +/// Combines logic: mirrors (if needed) AND adds material value. +/// This happens at compile-time, so no runtime cost. +const fn prepare_table(table: [i32; 64], material: i32, mirror: bool) -> [i32; 64] { + let mut out = [0; 64]; let mut i = 0; while i < 64 { - // XOR 56 maps rank 1 to 8, 2 to 7 etc, keeping files intact - mirrored[i] = table[i ^ 56]; + let idx = if mirror { i ^ 56 } else { i }; + out[i] = table[idx] + material; i += 1; } - mirrored + out } // Type signature: [Piece (6)] -> [Color (2)] -> [Phase (2)] -> [Square (64)] pub const PSQT: [[[[i32; 64]; 2]; 2]; 6] = [ // 1. PAWN [ - [mirror_psqt(MG_PAWN_TABLE), mirror_psqt(EG_PAWN_TABLE)], // White (Muss geflippt werden!) - [MG_PAWN_TABLE, EG_PAWN_TABLE] // Black (Ist bereits korrekt für schwarze Indices) + [prepare_table(MG_PAWN_TABLE, MG_PAWN_VAL, true), prepare_table(EG_PAWN_TABLE, EG_PAWN_VAL, true)], // White (Mirrored + Mat) + [prepare_table(MG_PAWN_TABLE, MG_PAWN_VAL, false), prepare_table(EG_PAWN_TABLE, EG_PAWN_VAL, false)] // Black (Normal + Mat) ], // 2. KNIGHT [ - [mirror_psqt(MG_KNIGHT_TABLE), mirror_psqt(EG_KNIGHT_TABLE)], // White - [MG_KNIGHT_TABLE, EG_KNIGHT_TABLE] // Black + [prepare_table(MG_KNIGHT_TABLE, MG_KNIGHT_VAL, true), prepare_table(EG_KNIGHT_TABLE, EG_KNIGHT_VAL, true)], + [prepare_table(MG_KNIGHT_TABLE, MG_KNIGHT_VAL, false), prepare_table(EG_KNIGHT_TABLE, EG_KNIGHT_VAL, false)] ], // 3. BISHOP [ - [mirror_psqt(MG_BISHOP_TABLE), mirror_psqt(EG_BISHOP_TABLE)], // White - [MG_BISHOP_TABLE, EG_BISHOP_TABLE] // Black + [prepare_table(MG_BISHOP_TABLE, MG_BISHOP_VAL, true), prepare_table(EG_BISHOP_TABLE, EG_BISHOP_VAL, true)], + [prepare_table(MG_BISHOP_TABLE, MG_BISHOP_VAL, false), prepare_table(EG_BISHOP_TABLE, EG_BISHOP_VAL, false)] ], // 4. ROOK [ - [mirror_psqt(MG_ROOK_TABLE), mirror_psqt(EG_ROOK_TABLE)], // White - [MG_ROOK_TABLE, EG_ROOK_TABLE] // Black + [prepare_table(MG_ROOK_TABLE, MG_ROOK_VAL, true), prepare_table(EG_ROOK_TABLE, EG_ROOK_VAL, true)], + [prepare_table(MG_ROOK_TABLE, MG_ROOK_VAL, false), prepare_table(EG_ROOK_TABLE, EG_ROOK_VAL, false)] ], // 5. QUEEN [ - [mirror_psqt(MG_QUEEN_TABLE), mirror_psqt(EG_QUEEN_TABLE)], // White - [MG_QUEEN_TABLE, EG_QUEEN_TABLE] // Black + [prepare_table(MG_QUEEN_TABLE, MG_QUEEN_VAL, true), prepare_table(EG_QUEEN_TABLE, EG_QUEEN_VAL, true)], + [prepare_table(MG_QUEEN_TABLE, MG_QUEEN_VAL, false), prepare_table(EG_QUEEN_TABLE, EG_QUEEN_VAL, false)] ], // 6. KING [ - [mirror_psqt(MG_KING_TABLE), mirror_psqt(EG_KING_TABLE)], // White - [MG_KING_TABLE, EG_KING_TABLE] // Black + [prepare_table(MG_KING_TABLE, MG_KING_VAL, true), prepare_table(EG_KING_TABLE, EG_KING_VAL, true)], + [prepare_table(MG_KING_TABLE, MG_KING_VAL, false), prepare_table(EG_KING_TABLE, EG_KING_VAL, false)] ], -]; - +]; \ No newline at end of file