Skip to content

Commit decb74e

Browse files
committed
Inefficient PeSTO PSQT
1 parent 2985a9e commit decb74e

File tree

3 files changed

+236
-61
lines changed

3 files changed

+236
-61
lines changed

src/algorithms/the_algorithm.rs

+84-46
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_hash::FxHasher;
44

55
use chess::{Action, Board, BoardStatus, ChessMove, Color, MoveGen, Piece, BitBoard};
66

7-
use crate::common::constants::{modules::{self, *}, position_bonus_tables::*};
7+
use crate::common::constants::{modules::{self, *}, naive_psqt_tables::*, tapered_pesto_psqt_tables::*};
88
use crate::common::utils::{self, module_enabled, Stats};
99

1010
use super::utils::{Evaluation, TranspositionEntry};
@@ -17,12 +17,12 @@ pub(crate) struct Algorithm {
1717
/// Number of times that a given board has been played
1818
pub(crate) board_played_times: HashMap<Board, u32>,
1919
pub(crate) pawn_hash: HashMap<BitBoard, f32>,
20-
pub(crate) position_pawn_hash: HashMap<BitBoard, f32>,
21-
pub(crate) position_rook_hash: HashMap<BitBoard, f32>,
22-
pub(crate) position_king_hash: HashMap<BitBoard, f32>,
23-
pub(crate) position_queen_hash: HashMap<BitBoard, f32>,
24-
pub(crate) position_knight_hash: HashMap<BitBoard, f32>,
25-
pub(crate) position_bishop_hash: HashMap<BitBoard, f32>
20+
pub(crate) naive_psqt_pawn_hash: HashMap<BitBoard, f32>,
21+
pub(crate) naive_psqt_rook_hash: HashMap<BitBoard, f32>,
22+
pub(crate) naive_psqt_king_hash: HashMap<BitBoard, f32>,
23+
pub(crate) naive_psqt_queen_hash: HashMap<BitBoard, f32>,
24+
pub(crate) naive_psqt_knight_hash: HashMap<BitBoard, f32>,
25+
pub(crate) naive_psqt_bishop_hash: HashMap<BitBoard, f32>
2626

2727
}
2828

@@ -34,12 +34,12 @@ impl Algorithm {
3434
time_per_move,
3535
board_played_times: HashMap::new(),
3636
pawn_hash: HashMap::new(),
37-
position_knight_hash: HashMap::new(),
38-
position_pawn_hash: HashMap::new(),
39-
position_rook_hash: HashMap::new(),
40-
position_bishop_hash: HashMap::new(),
41-
position_queen_hash: HashMap::new(),
42-
position_king_hash: HashMap::new(),
37+
naive_psqt_knight_hash: HashMap::new(),
38+
naive_psqt_pawn_hash: HashMap::new(),
39+
naive_psqt_rook_hash: HashMap::new(),
40+
naive_psqt_bishop_hash: HashMap::new(),
41+
naive_psqt_queen_hash: HashMap::new(),
42+
naive_psqt_king_hash: HashMap::new(),
4343
}
4444
}
4545

@@ -60,7 +60,7 @@ impl Algorithm {
6060

6161
if depth == 0 {
6262
stats.leaves_visited += 1;
63-
let eval = self.eval(board, board_played_times_prediction);
63+
let eval = self.eval(board, board_played_times_prediction, 0.);
6464
// if module_enabled(self.modules, TRANSPOSITION_TABLE) {
6565
// let start = Instant::now();
6666
// self.transposition_table
@@ -330,6 +330,10 @@ impl Algorithm {
330330
action = Action::DeclareDraw;
331331
}
332332
self.board_played_times.insert(new_board, old_value + 1);
333+
334+
if utils::module_enabled(self.modules, modules::TAPERED_INCREMENTAL_PESTO_PSQT) {
335+
336+
}
333337
}
334338

335339
(action, deepest_complete_output.1, deepest_complete_output.2)
@@ -339,6 +343,7 @@ impl Algorithm {
339343
&mut self,
340344
board: &Board,
341345
board_played_times_prediction: &HashMap<Board, u32>,
346+
incremental_eval: f32,
342347
) -> f32 {
343348
let board_status = board.status();
344349
if board_status == BoardStatus::Stalemate {
@@ -372,40 +377,73 @@ impl Algorithm {
372377
}
373378

374379
//Compares piece position with an 8x8 table containing certain values. The value corresponding to the position of the piece gets added as evaluation.
375-
let mut position_bonus: f32 = 0.;
376-
if utils::module_enabled(self.modules, modules::POSITION_BONUS) {
377-
fn position_bonus_calc(position_table: [f32; 64], piece_bitboard: &BitBoard, color_bitboard: &BitBoard) -> f32 {
378-
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with position bonus constants.
380+
let mut naive_psqt: f32 = 0.;
381+
if utils::module_enabled(self.modules, modules::NAIVE_PSQT) {
382+
fn naive_psqt_calc(naive_psqt_table: [f32; 64], piece_bitboard: &BitBoard, color_bitboard: &BitBoard) -> f32 {
383+
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with NAIVE_PSQT bonus constants.
379384
let mut bonus: f32 = 0.;
380-
//Get's the bitboard with all piece positions, and runs bitwise and for the board having one's own colors.
385+
//Get's the bitboard with all piece NAIVE_PSQTs, and runs bitwise and for the board having one's own colors.
381386
for i in 0..63 {
382-
//The position table and bitboard are flipped vertically, hence .reverse_colors(). Reverse colors is for some reason faster than replacing i with 56-i+2*(i%8).
383-
bonus += ((piece_bitboard & color_bitboard).reverse_colors().to_size(0) >> i & 1) as f32 * position_table[i];
387+
//The naive_psqt table and bitboard are flipped vertically, hence .reverse_colors(). Reverse colors is for some reason faster than replacing i with 56-i+2*(i%8).
388+
bonus += ((piece_bitboard & color_bitboard).reverse_colors().to_size(0) >> i & 1) as f32 * naive_psqt_table[i];
384389
}
385390
return bonus;
386391
}
387392

388-
fn in_hash_map(bitboard: &BitBoard, color_bitboard: &BitBoard, position_table: [f32; 64], position_hash_map: &mut HashMap::<BitBoard, f32>) -> f32 {
389-
if !position_hash_map.contains_key(&(bitboard & color_bitboard)) {
390-
position_hash_map.insert(bitboard & color_bitboard, position_bonus_calc(position_table, bitboard, color_bitboard));
393+
//Utilizes hashmaps so we don't have to recalculate the entire bonus for all pieces every move. This is slightly faster.
394+
fn in_hash_map(bitboard: &BitBoard, color_bitboard: &BitBoard, naive_psqt_table: [f32; 64], naive_psqt_hash_map: &mut HashMap::<BitBoard, f32>) -> f32 {
395+
if !naive_psqt_hash_map.contains_key(&(bitboard & color_bitboard)) {
396+
naive_psqt_hash_map.insert(bitboard & color_bitboard, naive_psqt_calc(naive_psqt_table, bitboard, color_bitboard));
397+
}
398+
return *naive_psqt_hash_map.get(&(bitboard & color_bitboard)).unwrap();
399+
}
400+
401+
if board.side_to_move() == Color::White {
402+
naive_psqt += in_hash_map(board.pieces(Piece::Pawn), board.color_combined(Color::White), NAIVE_PSQT_TABLE_PAWN, &mut self.naive_psqt_pawn_hash);
403+
naive_psqt += in_hash_map(board.pieces(Piece::Rook), board.color_combined(Color::White), NAIVE_PSQT_TABLE_ROOK, &mut self.naive_psqt_rook_hash);
404+
naive_psqt += in_hash_map(board.pieces(Piece::King), board.color_combined(Color::White), NAIVE_PSQT_TABLE_KING, &mut self.naive_psqt_king_hash);
405+
naive_psqt += in_hash_map(board.pieces(Piece::Queen), board.color_combined(Color::White), NAIVE_PSQT_TABLE_QUEEN, &mut self.naive_psqt_queen_hash);
406+
naive_psqt += in_hash_map(board.pieces(Piece::Bishop), board.color_combined(Color::White), NAIVE_PSQT_TABLE_BISHOP, &mut self.naive_psqt_bishop_hash);
407+
naive_psqt += in_hash_map(board.pieces(Piece::Knight), board.color_combined(Color::White), NAIVE_PSQT_TABLE_KNIGHT, &mut self.naive_psqt_knight_hash);
408+
} else {
409+
naive_psqt += in_hash_map(board.pieces(Piece::Pawn), board.color_combined(Color::Black), NAIVE_PSQT_TABLE_PAWN, &mut self.naive_psqt_pawn_hash);
410+
naive_psqt += in_hash_map(board.pieces(Piece::Rook), board.color_combined(Color::Black), NAIVE_PSQT_TABLE_ROOK, &mut self.naive_psqt_rook_hash);
411+
naive_psqt += in_hash_map(board.pieces(Piece::King), board.color_combined(Color::Black), NAIVE_PSQT_TABLE_KING, &mut self.naive_psqt_king_hash);
412+
naive_psqt += in_hash_map(board.pieces(Piece::Queen), board.color_combined(Color::Black), NAIVE_PSQT_TABLE_QUEEN, &mut self.naive_psqt_queen_hash);
413+
naive_psqt += in_hash_map(board.pieces(Piece::Bishop), board.color_combined(Color::Black), NAIVE_PSQT_TABLE_BISHOP, &mut self.naive_psqt_bishop_hash);
414+
naive_psqt += in_hash_map(board.pieces(Piece::Knight), board.color_combined(Color::Black), NAIVE_PSQT_TABLE_KNIGHT, &mut self.naive_psqt_knight_hash);
415+
}
416+
}
417+
418+
let mut tapered_pesto: f32 = 0.;
419+
if utils::module_enabled(self.modules, modules::TAPERED_EVERY_PRESTO_PSQT) {
420+
fn tapered_psqt_calc(piece_bitboard: &BitBoard, color_bitboard: &BitBoard, material: (u32, u32), tapered_table_mg: [f32; 64], tapered_table_eg: [f32; 64]) -> f32 {
421+
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with NAIVE_PSQT bonus constants.
422+
let mut bonus: f32 = 0.;
423+
//Get's the bitboard with all piece NAIVE_PSQTs, and runs bitwise and for the board having one's own colors.
424+
for i in 0..63 {
425+
//The psqt tables and bitboards are flipped vertically, hence .reverse_colors(). Reverse colors is for some reason faster than replacing i with 56-i+2*(i%8).
426+
//By being tapered, it means that we have an opening + middlgame and an endgame PSQT, and we (hopefully?) linerarly transition from one to the other, depending on material value.
427+
bonus += ((piece_bitboard & color_bitboard).reverse_colors().to_size(0) >> i & 1) as f32 *
428+
((material.0 + material.1 - 2000) as f32 / 78. * tapered_table_mg[i] + (material.0 + material.1 - 2000 + 78) as f32 / 78. * tapered_table_eg[i]) as f32;
391429
}
392-
return *position_hash_map.get(&(bitboard & color_bitboard)).unwrap();
430+
return bonus;
393431
}
394432

395433
if board.side_to_move() == Color::White {
396-
position_bonus += in_hash_map(board.pieces(Piece::Pawn), board.color_combined(Color::White), POSITION_BONUS_TABLE_PAWN, &mut self.position_pawn_hash);
397-
position_bonus += in_hash_map(board.pieces(Piece::Rook), board.color_combined(Color::White), POSITION_BONUS_TABLE_ROOK, &mut self.position_rook_hash);
398-
position_bonus += in_hash_map(board.pieces(Piece::King), board.color_combined(Color::White), POSITION_BONUS_TABLE_KING, &mut self.position_king_hash);
399-
position_bonus += in_hash_map(board.pieces(Piece::Queen), board.color_combined(Color::White), POSITION_BONUS_TABLE_QUEEN, &mut self.position_queen_hash);
400-
position_bonus += in_hash_map(board.pieces(Piece::Bishop), board.color_combined(Color::White), POSITION_BONUS_TABLE_BISHOP, &mut self.position_bishop_hash);
401-
position_bonus += in_hash_map(board.pieces(Piece::Knight), board.color_combined(Color::White), POSITION_BONUS_TABLE_KNIGHT, &mut self.position_knight_hash);
434+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Pawn), board.color_combined(Color::White), material_each_side, TAPERED_MG_PESTO_PAWN, TAPERED_EG_PESTO_PAWN);
435+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Rook), board.color_combined(Color::White), material_each_side, TAPERED_MG_PESTO_ROOK, TAPERED_EG_PESTO_ROOK);
436+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::King), board.color_combined(Color::White), material_each_side, TAPERED_MG_PESTO_KING, TAPERED_EG_PESTO_KING);
437+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Queen), board.color_combined(Color::White), material_each_side, TAPERED_MG_PESTO_QUEEN, TAPERED_EG_PESTO_QUEEN);
438+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Bishop), board.color_combined(Color::White), material_each_side, TAPERED_MG_PESTO_BISHOP, TAPERED_EG_PESTO_BISHOP);
439+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Knight), board.color_combined(Color::White), material_each_side, TAPERED_MG_PESTO_KNIGHT, TAPERED_EG_PESTO_KNIGT);
402440
} else {
403-
position_bonus += in_hash_map(board.pieces(Piece::Pawn), board.color_combined(Color::Black), POSITION_BONUS_TABLE_PAWN, &mut self.position_pawn_hash);
404-
position_bonus += in_hash_map(board.pieces(Piece::Rook), board.color_combined(Color::Black), POSITION_BONUS_TABLE_ROOK, &mut self.position_rook_hash);
405-
position_bonus += in_hash_map(board.pieces(Piece::King), board.color_combined(Color::Black), POSITION_BONUS_TABLE_KING, &mut self.position_king_hash);
406-
position_bonus += in_hash_map(board.pieces(Piece::Queen), board.color_combined(Color::Black), POSITION_BONUS_TABLE_QUEEN, &mut self.position_queen_hash);
407-
position_bonus += in_hash_map(board.pieces(Piece::Bishop), board.color_combined(Color::Black), POSITION_BONUS_TABLE_BISHOP, &mut self.position_bishop_hash);
408-
position_bonus += in_hash_map(board.pieces(Piece::Knight), board.color_combined(Color::Black), POSITION_BONUS_TABLE_KNIGHT, &mut self.position_knight_hash);
441+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Pawn), board.color_combined(Color::Black), material_each_side, TAPERED_MG_PESTO_PAWN, TAPERED_EG_PESTO_PAWN);
442+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Rook), board.color_combined(Color::Black), material_each_side, TAPERED_MG_PESTO_ROOK, TAPERED_EG_PESTO_ROOK);
443+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::King), board.color_combined(Color::Black), material_each_side, TAPERED_MG_PESTO_KING, TAPERED_EG_PESTO_KING);
444+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Queen), board.color_combined(Color::Black), material_each_side, TAPERED_MG_PESTO_QUEEN, TAPERED_EG_PESTO_QUEEN);
445+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Bishop), board.color_combined(Color::Black), material_each_side, TAPERED_MG_PESTO_BISHOP, TAPERED_EG_PESTO_BISHOP);
446+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Knight), board.color_combined(Color::Black), material_each_side, TAPERED_MG_PESTO_KNIGHT, TAPERED_EG_PESTO_KNIGT);
409447
}
410448
}
411449

@@ -424,8 +462,8 @@ impl Algorithm {
424462
bonus -= 0.5*cmp::max((pawn_bitboard & (0x8080808080808080 >> i)).count_ones() as i64 - 1, 0) as f32;
425463
}
426464

427-
//king safety. Outer 3 pawns get +1 eval bonus per pawn if king is behind them. King position required is either ..X..... or ......X.
428-
bonus += ((king_bitboard & 0x2).count_ones() * (pawn_bitboard & 0x7).count_ones() + (king_bitboard & 0x20).count_ones() * (pawn_bitboard & 0xE000).count_ones()) as f32;
465+
//king safety. Outer 3 pawns get +1 eval bonus per pawn if king is behind them. King naive_psqt required is either ..X..... or ......X.
466+
bonus += ((king_bitboard & 0x2).count_ones() * (pawn_bitboard & 0x107).count_ones() + (king_bitboard & 0x20).count_ones() * (pawn_bitboard & 0x80E000).count_ones()) as f32;
429467
return bonus;
430468
}
431469

@@ -445,19 +483,19 @@ impl Algorithm {
445483
}
446484
}
447485

448-
let evaluation: f32 = controlled_squares as f32 / 20. + diff_material as f32 + position_bonus + pawn_structure;
486+
let evaluation: f32 = controlled_squares as f32 / 20. + diff_material as f32 + naive_psqt + pawn_structure + tapered_pesto;
449487
return evaluation
450488
}
451489

452490
pub(crate) fn reset(&mut self) {
453491
self.transposition_table = HashMap::new();
454492
self.board_played_times = HashMap::new();
455493
self.pawn_hash = HashMap::new();
456-
self.position_pawn_hash = HashMap::new();
457-
self.position_king_hash = HashMap::new();
458-
self.position_queen_hash = HashMap::new();
459-
self.position_bishop_hash = HashMap::new();
460-
self.position_rook_hash = HashMap::new();
461-
self.position_knight_hash = HashMap::new();
494+
self.naive_psqt_pawn_hash = HashMap::new();
495+
self.naive_psqt_king_hash = HashMap::new();
496+
self.naive_psqt_queen_hash = HashMap::new();
497+
self.naive_psqt_bishop_hash = HashMap::new();
498+
self.naive_psqt_rook_hash = HashMap::new();
499+
self.naive_psqt_knight_hash = HashMap::new();
462500
}
463501
}

0 commit comments

Comments
 (0)