Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Tearth committed Aug 19, 2024
1 parent d522125 commit ad8da35
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 62 deletions.
14 changes: 5 additions & 9 deletions src/evaluation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::state::*;
use crate::utils::bithelpers::BitHelpers;
use pst::*;
use std::hint::unreachable_unchecked;
use std::ops;

pub mod material;
Expand Down Expand Up @@ -54,23 +55,18 @@ pub struct EvaluationResult {

impl EvaluationParameters {
/// Gets a PST value for the specified `color`, `piece`, `phase` and `square`.
pub fn get_pst_value(&self, color: usize, piece: usize, king_file: usize, phase: usize, mut square: usize) -> i16 {
if color == BLACK {
// king_file = (1u64 << (king_file & 0x3f)).swap_bytes().bit_scan();
square = (1u64 << square).swap_bytes().bit_scan();
}

pub fn get_pst_value(&self, piece: usize, king_square: usize, phase: usize, square: usize) -> i16 {
let pst = match piece {
PAWN => &Self::PAWN_PST_PATTERN,
KNIGHT => &Self::KNIGHT_PST_PATTERN,
BISHOP => &Self::BISHOP_PST_PATTERN,
ROOK => &Self::ROOK_PST_PATTERN,
QUEEN => &Self::QUEEN_PST_PATTERN,
KING => &Self::KING_PST_PATTERN,
_ => panic!("Invalid value: piece={}", piece),
_ => unsafe { unreachable_unchecked() },
};

pst[king_file & 0x3f][phase][63 - square]
pst[KING_BUCKETS[63 - king_square]][phase][63 - square]
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/evaluation/pawns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ use crate::utils::bithelpers::BitHelpers;
use crate::utils::conditional_expression;
use std::cmp;

#[cfg(feature = "dev")]
use pst::*;

#[cfg(feature = "dev")]
use crate::tuning::tuner::TunerCoefficient;

Expand Down
2 changes: 1 addition & 1 deletion src/evaluation/pst/bishop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;

impl EvaluationParameters {
#[rustfmt::skip]
pub const BISHOP_PST_PATTERN: [[[i16; 64]; 2]; 8] =
pub const BISHOP_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =
[
[
[
Expand Down
2 changes: 1 addition & 1 deletion src/evaluation/pst/king.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;

impl EvaluationParameters {
#[rustfmt::skip]
pub const KING_PST_PATTERN: [[[i16; 64]; 2]; 8] =
pub const KING_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =
[
[
[
Expand Down
2 changes: 1 addition & 1 deletion src/evaluation/pst/knight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;

impl EvaluationParameters {
#[rustfmt::skip]
pub const KNIGHT_PST_PATTERN: [[[i16; 64]; 2]; 8] =
pub const KNIGHT_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =
[
[
[
Expand Down
34 changes: 28 additions & 6 deletions src/evaluation/pst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ pub mod pawn;
pub mod queen;
pub mod rook;

pub const KING_BUCKETS_COUNT: usize = 8;

#[rustfmt::skip]
pub const KING_BUCKETS: [usize; 64] = [
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0,
];

/// Evaluates piece-square table value on the `board` and returns score from the white color perspective (more than 0 when advantage, less than 0 when disadvantage).
/// This evaluator sums all values of the pieces for the specified squares, using incremental counters in `board`.
pub fn evaluate(board: &Board) -> EvaluationResult {
Expand All @@ -24,17 +38,25 @@ pub fn evaluate(board: &Board) -> EvaluationResult {
/// Recalculates incremental counters on the `board`. This function should be called only once during board initialization, as it's too slow in regular search.
pub fn recalculate_incremental_values(board: &mut Board) {
for color_index in ALL_COLORS {
let king_file = board.pieces[color_index][KING].bit_scan() & 7;
let mut king_square = board.pieces[color_index][KING].bit_scan() & 0x3f;
if color_index == BLACK {
king_square = (1u64 << king_square).swap_bytes().bit_scan();
}

for phase in ALL_PHASES {
let mut score = 0;
for piece_index in ALL_PIECES {
let mut pieces_bb = board.pieces[color_index][piece_index];
while pieces_bb != 0 {
let square_bb = pieces_bb.get_lsb();
let square = square_bb.bit_scan();
let mut square = square_bb.bit_scan();
pieces_bb = pieces_bb.pop_lsb();

score += board.evaluation_parameters.get_pst_value(color_index, piece_index, king_file, phase, square);
if color_index == BLACK {
square = (1u64 << square).swap_bytes().bit_scan();
}

score += board.evaluation_parameters.get_pst_value(piece_index, king_square, phase, square);
}
}

Expand All @@ -46,9 +68,9 @@ pub fn recalculate_incremental_values(board: &mut Board) {
/// Gets coefficients of piece-square table for `piece` on `board` and assigns indexes starting from `index`.
#[cfg(feature = "dev")]
pub fn get_coefficients(board: &Board, piece: usize, index: &mut u16, coefficients: &mut Vec<TunerCoefficient>, indices: &mut Vec<u16>) {
for king_file in ALL_FILES {
let valid_for_white = king_file == board.pieces[WHITE][KING].bit_scan() & 7;
let valid_for_black = king_file == board.pieces[BLACK][KING].bit_scan() & 7;
for bucket in 0..KING_BUCKETS_COUNT {
let valid_for_white = bucket == KING_BUCKETS[63 - board.pieces[WHITE][KING].bit_scan()];
let valid_for_black = bucket == KING_BUCKETS[63 - board.pieces[BLACK][KING].bit_scan()];

for game_phase in ALL_PHASES {
for square in ALL_SQUARES {
Expand Down
2 changes: 1 addition & 1 deletion src/evaluation/pst/pawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;

impl EvaluationParameters {
#[rustfmt::skip]
pub const PAWN_PST_PATTERN: [[[i16; 64]; 2]; 8] =
pub const PAWN_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =
[
[
[
Expand Down
2 changes: 1 addition & 1 deletion src/evaluation/pst/queen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;

impl EvaluationParameters {
#[rustfmt::skip]
pub const QUEEN_PST_PATTERN: [[[i16; 64]; 2]; 8] =
pub const QUEEN_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =
[
[
[
Expand Down
2 changes: 1 addition & 1 deletion src/evaluation/pst/rook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;

impl EvaluationParameters {
#[rustfmt::skip]
pub const ROOK_PST_PATTERN: [[[i16; 64]; 2]; 8] =
pub const ROOK_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =
[
[
[
Expand Down
3 changes: 0 additions & 3 deletions src/evaluation/safety.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use super::*;
use crate::state::representation::Board;

#[cfg(feature = "dev")]
use pst::*;

#[cfg(feature = "dev")]
use crate::tuning::tuner::TunerCoefficient;

Expand Down
55 changes: 40 additions & 15 deletions src/state/representation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::evaluation::material;
use crate::evaluation::mobility;
use crate::evaluation::pawns;
use crate::evaluation::pst;
use crate::evaluation::pst::*;
use crate::evaluation::safety;
use crate::evaluation::EvaluationParameters;
use crate::evaluation::*;
Expand Down Expand Up @@ -350,7 +351,12 @@ impl Board {
self.pawn_hash ^= self.zobrist.get_piece_hash(color, KING, from);
self.pawn_hash ^= self.zobrist.get_piece_hash(color, KING, to);

pst::recalculate_incremental_values(self);
let from = if color == WHITE { from } else { (1u64 << from).swap_bytes().bit_scan() };
let to = if color == WHITE { to } else { (1u64 << to).swap_bytes().bit_scan() };

if KING_BUCKETS[from] != KING_BUCKETS[to] {
pst::recalculate_incremental_values(self);
}
} else if piece == ROOK {
match color {
WHITE => match from {
Expand Down Expand Up @@ -688,49 +694,68 @@ impl Board {
}

/// Adds `piece` on the `square` with the specified `color`, also updates occupancy and incremental values.
pub fn add_piece<const UNDO: bool>(&mut self, color: usize, piece: usize, square: usize) {
pub fn add_piece<const UNDO: bool>(&mut self, color: usize, piece: usize, mut square: usize) {
self.pieces[color][piece] |= 1u64 << square;
self.occupancy[color] |= 1u64 << square;
self.piece_table[square] = piece as u8;
self.material_scores[color] += self.evaluation_parameters.piece_value[piece];
self.game_phase += PIECE_PHASE_VALUE[piece];

if !UNDO {
let king_file = self.pieces[color][KING].bit_scan() & 7;
self.pst_scores[color][OPENING] += self.evaluation_parameters.get_pst_value(color, piece, king_file, OPENING, square);
self.pst_scores[color][ENDING] += self.evaluation_parameters.get_pst_value(color, piece, king_file, ENDING, square);
let mut king_square = self.pieces[color][KING].bit_scan() & 0x3f;

if color == BLACK {
king_square = (1u64 << king_square).swap_bytes().bit_scan();
square = (1u64 << square).swap_bytes().bit_scan();
}

self.pst_scores[color][OPENING] += self.evaluation_parameters.get_pst_value(piece, king_square, OPENING, square);
self.pst_scores[color][ENDING] += self.evaluation_parameters.get_pst_value(piece, king_square, ENDING, square);
}
}

/// Removes `piece` on the `square` with the specified `color`, also updates occupancy and incremental values.
pub fn remove_piece<const UNDO: bool>(&mut self, color: usize, piece: usize, square: usize) {
pub fn remove_piece<const UNDO: bool>(&mut self, color: usize, piece: usize, mut square: usize) {
self.pieces[color][piece] &= !(1u64 << square);
self.occupancy[color] &= !(1u64 << square);
self.piece_table[square] = u8::MAX;
self.material_scores[color] -= self.evaluation_parameters.piece_value[piece];
self.game_phase -= PIECE_PHASE_VALUE[piece];

if !UNDO {
let king_file = self.pieces[color][KING].bit_scan() & 7;
self.pst_scores[color][OPENING] -= self.evaluation_parameters.get_pst_value(color, piece, king_file, OPENING, square);
self.pst_scores[color][ENDING] -= self.evaluation_parameters.get_pst_value(color, piece, king_file, ENDING, square);
let mut king_square = self.pieces[color][KING].bit_scan() & 0x3f;

if color == BLACK {
king_square = (1u64 << king_square).swap_bytes().bit_scan();
square = (1u64 << square).swap_bytes().bit_scan();
}

self.pst_scores[color][OPENING] -= self.evaluation_parameters.get_pst_value(piece, king_square, OPENING, square);
self.pst_scores[color][ENDING] -= self.evaluation_parameters.get_pst_value(piece, king_square, ENDING, square);
}
}

/// Moves `piece` from the square specified by `from` to the square specified by `to` with the specified `color`, also updates occupancy and incremental values.
pub fn move_piece<const UNDO: bool>(&mut self, color: usize, piece: usize, from: usize, to: usize) {
pub fn move_piece<const UNDO: bool>(&mut self, color: usize, piece: usize, mut from: usize, mut to: usize) {
self.pieces[color][piece] ^= (1u64 << from) | (1u64 << to);
self.occupancy[color] ^= (1u64 << from) | (1u64 << to);

self.piece_table[to] = self.piece_table[from];
self.piece_table[from] = u8::MAX;

if !UNDO {
let king_file = self.pieces[color][KING].bit_scan() & 7;
self.pst_scores[color][OPENING] -= self.evaluation_parameters.get_pst_value(color, piece, king_file, OPENING, from);
self.pst_scores[color][ENDING] -= self.evaluation_parameters.get_pst_value(color, piece, king_file, ENDING, from);
self.pst_scores[color][OPENING] += self.evaluation_parameters.get_pst_value(color, piece, king_file, OPENING, to);
self.pst_scores[color][ENDING] += self.evaluation_parameters.get_pst_value(color, piece, king_file, ENDING, to);
let mut king_square = self.pieces[color][KING].bit_scan() & 0x3f;

if color == BLACK {
king_square = (1u64 << king_square).swap_bytes().bit_scan();
from = (1u64 << from).swap_bytes().bit_scan();
to = (1u64 << to).swap_bytes().bit_scan();
}

self.pst_scores[color][OPENING] -= self.evaluation_parameters.get_pst_value(piece, king_square, OPENING, from);
self.pst_scores[color][ENDING] -= self.evaluation_parameters.get_pst_value(piece, king_square, ENDING, from);
self.pst_scores[color][OPENING] += self.evaluation_parameters.get_pst_value(piece, king_square, OPENING, to);
self.pst_scores[color][ENDING] += self.evaluation_parameters.get_pst_value(piece, king_square, ENDING, to);
}
}

Expand Down
41 changes: 21 additions & 20 deletions src/tuning/tuner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::evaluation::material;
use crate::evaluation::mobility;
use crate::evaluation::pawns;
use crate::evaluation::pst;
use crate::evaluation::pst::*;
use crate::evaluation::safety;
use crate::evaluation::EvaluationParameters;
use crate::evaluation::*;
Expand Down Expand Up @@ -448,39 +449,39 @@ fn load_values(random_values: bool) -> Vec<TunerParameter> {
parameters.append(&mut evaluation_parameters.king_attacked_squares_ending.iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());

let pawn_pst = &EvaluationParameters::PAWN_PST_PATTERN;
for king_file in ALL_FILES {
parameters.append(&mut pawn_pst[king_file][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut pawn_pst[king_file][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
for king_bucket in 0..KING_BUCKETS_COUNT {
parameters.append(&mut pawn_pst[king_bucket][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut pawn_pst[king_bucket][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
}

let knight_pst = &EvaluationParameters::KNIGHT_PST_PATTERN;
for king_file in ALL_FILES {
parameters.append(&mut knight_pst[king_file][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut knight_pst[king_file][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
for king_bucket in 0..KING_BUCKETS_COUNT {
parameters.append(&mut knight_pst[king_bucket][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut knight_pst[king_bucket][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
}

let bishop_pst = &EvaluationParameters::BISHOP_PST_PATTERN;
for king_file in ALL_FILES {
parameters.append(&mut bishop_pst[king_file][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut bishop_pst[king_file][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
for king_bucket in 0..KING_BUCKETS_COUNT {
parameters.append(&mut bishop_pst[king_bucket][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut bishop_pst[king_bucket][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
}

let rook_pst = &EvaluationParameters::ROOK_PST_PATTERN;
for king_file in ALL_FILES {
parameters.append(&mut rook_pst[king_file][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut rook_pst[king_file][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
for king_bucket in 0..KING_BUCKETS_COUNT {
parameters.append(&mut rook_pst[king_bucket][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut rook_pst[king_bucket][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
}

let queen_pst = &EvaluationParameters::QUEEN_PST_PATTERN;
for king_file in ALL_FILES {
parameters.append(&mut queen_pst[king_file][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut queen_pst[king_file][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
for king_bucket in 0..KING_BUCKETS_COUNT {
parameters.append(&mut queen_pst[king_bucket][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut queen_pst[king_bucket][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
}

let king_pst = &EvaluationParameters::KING_PST_PATTERN;
for king_file in ALL_FILES {
parameters.append(&mut king_pst[king_file][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut king_pst[king_file][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
for king_bucket in 0..KING_BUCKETS_COUNT {
parameters.append(&mut king_pst[king_bucket][0].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
parameters.append(&mut king_pst[king_bucket][1].iter().map(|v| TunerParameter::new(*v, -999, -40, 40, 999)).collect());
}

if random_values {
Expand Down Expand Up @@ -560,10 +561,10 @@ fn write_piece_square_table(weights: &mut Iter<f32>, output_directory: &str, bes
output.push('\n');
output.push_str("impl EvaluationParameters {\n");
output.push_str(" #[rustfmt::skip]\n");
output.push_str(&format!(" pub const {}_PST_PATTERN: [[[i16; 64]; 2]; 8] =\n", name));
output.push_str(&format!(" pub const {}_PST_PATTERN: [[[i16; 64]; 2]; KING_BUCKETS_COUNT] =\n", name));
output.push_str(" [\n");

for _ in ALL_FILES {
for _ in 0..KING_BUCKETS_COUNT {
output.push_str(" [\n");
output.push_str(" [\n");
output.push_str(get_piece_square_table(weights).as_str());
Expand Down

0 comments on commit ad8da35

Please sign in to comment.