Skip to content

Commit d877e96

Browse files
committed
Incremental PSQT... but with logic error
1 parent decb74e commit d877e96

File tree

6 files changed

+231
-108
lines changed

6 files changed

+231
-108
lines changed

Cargo.lock

-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ edition = "2021"
99
#bevy = { version = "0.11.2", features = ["dynamic_linking"] }
1010
chess = "3.2.0"
1111
rand = "0.8.5"
12-
rustc-hash = "1.1.0"
1312
tokio = { version = "1.34.0", features = ["full"] }
1413
# ordered_float = "4.1.1"

src/algorithms/the_algorithm.rs

+139-30
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use std::{collections::HashMap, cmp};
22
use tokio::time::{Duration, Instant};
3-
use rustc_hash::FxHasher;
43

5-
use chess::{Action, Board, BoardStatus, ChessMove, Color, MoveGen, Piece, BitBoard};
4+
use chess::{Action, Board, BoardStatus, ChessMove, Color, MoveGen, Piece, BitBoard, Square};
65

76
use crate::common::constants::{modules::{self, *}, naive_psqt_tables::*, tapered_pesto_psqt_tables::*};
87
use crate::common::utils::{self, module_enabled, Stats};
@@ -55,25 +54,31 @@ impl Algorithm {
5554
stats: &mut Stats,
5655
num_extensions: u32,
5756
board_played_times_prediction: &mut HashMap<Board, u32>,
57+
mut white_incremental_psqt_eval: f32,
58+
mut black_incremental_psqt_eval: f32,
5859
) -> Evaluation {
5960

6061

6162
if depth == 0 {
6263
stats.leaves_visited += 1;
63-
let eval = self.eval(board, board_played_times_prediction, 0.);
64+
let eval = self.eval(board, board_played_times_prediction);
6465
// if module_enabled(self.modules, TRANSPOSITION_TABLE) {
6566
// let start = Instant::now();
6667
// self.transposition_table
6768
// .insert(*board, TranspositionEntry::new(depth, eval, None));
6869
// stats.time_for_transposition_access += Instant::now() - start;
6970
// stats.transposition_table_entries += 1
7071
// }
71-
return Evaluation::new(Some(eval), None, None);
72+
let incremental_psqt_eval = white_incremental_psqt_eval;
73+
if board.side_to_move() == Color::Black {
74+
let incremental_psqt_eval = black_incremental_psqt_eval;
75+
}
76+
return Evaluation::new(Some(eval + incremental_psqt_eval), None, None, Some(white_incremental_psqt_eval), Some(black_incremental_psqt_eval));
7277
}
7378

7479
// Whether we should try to maximise the eval
7580
let maximise: bool = board.side_to_move() == Color::White;
76-
let mut best_evaluation = Evaluation::new(None, None, None);
81+
let mut best_evaluation = Evaluation::new(None, None, None, None, None);
7782

7883
let legal_moves = MoveGen::new_legal(board);
7984
let num_legal_moves = legal_moves.len();
@@ -162,6 +167,8 @@ impl Algorithm {
162167
Some(transposition_entry.unwrap().eval),
163168
transposition_entry.unwrap().next_action,
164169
None,
170+
Some(white_incremental_psqt_eval),
171+
Some(black_incremental_psqt_eval)
165172
)
166173
} else {
167174
board_played_times_prediction.insert(
@@ -178,6 +185,8 @@ impl Algorithm {
178185
stats,
179186
num_extensions + extend_by,
180187
board_played_times_prediction,
188+
white_incremental_psqt_eval,
189+
black_incremental_psqt_eval,
181190
);
182191
board_played_times_prediction.insert(
183192
new_board,
@@ -232,6 +241,106 @@ impl Algorithm {
232241
break;
233242
}
234243
}
244+
245+
if utils::module_enabled(self.modules, modules::TAPERED_INCREMENTAL_PESTO_PSQT) {
246+
247+
248+
fn match_piece_to_int(input: Option<Piece>) -> usize {
249+
match input {
250+
Some(Piece::Pawn) => 0,
251+
Some(Piece::Knight) => 1,
252+
Some(Piece::Bishop) => 2,
253+
Some(Piece::Rook) => 3,
254+
Some(Piece::Queen) => 4,
255+
Some(Piece::King) => 5,
256+
//Note: Returning a 6 is not intended, and must be handled on a case-by-case basis.
257+
None => 6
258+
}
259+
}
260+
261+
fn match_int_to_piece(input: u8) -> Piece {
262+
match input {
263+
0 => Piece::Pawn,
264+
1 => Piece::Knight,
265+
2 => Piece::Bishop,
266+
3 => Piece::Rook,
267+
4 => Piece::Queen,
268+
5 => Piece::King,
269+
//Any other input to the function besides 0..5 is terrible behaviour from the input case, and should not happen. I'm simply going to *not* handle that case. Good luck!
270+
6_u8..=u8::MAX => unimplemented!()
271+
}
272+
}
273+
274+
let material_each_side = utils::material_each_side(board);
275+
fn calc_increment(piece_type: usize, location: usize, material_each_side: (u32, u32)) -> f32 {
276+
return ((material_each_side.0 + material_each_side.1 - 2000) as f32 * TAPERED_MG_PESTO[piece_type][location] + (material_each_side.0 + material_each_side.1 - 2000 + 78) as f32 * TAPERED_EG_PESTO[piece_type][location]) as f32;
277+
}
278+
279+
fn calc_increment_all(board: &Board, color_bitboard: &BitBoard, material_each_side: (u32, u32)) -> f32 {
280+
let mut incremental_psqt_eval: f32 = 0.;
281+
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with NAIVE_PSQT bonus constants.
282+
//Get's the bitboard with all piece positions, and runs bitwise and for the board having one's own colors.
283+
//Iterates over all types of squares
284+
for j in 0..5 {
285+
//Iterates over all 64 squares on the board.
286+
for i in 0..63 {
287+
//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).
288+
//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.
289+
incremental_psqt_eval += ((board.pieces(match_int_to_piece(j)) & color_bitboard).reverse_colors().to_size(0) >> i & 1) as f32 *
290+
((material_each_side.0 + material_each_side.1 - 2000) as f32 * TAPERED_MG_PESTO[j as usize][i as usize] + (material_each_side.0 + material_each_side.1 - 2000 + 78) as f32 * TAPERED_EG_PESTO[j as usize][i as usize]) as f32 / 78.;
291+
}
292+
}
293+
return incremental_psqt_eval;
294+
}
295+
let moved_piece_type: usize = match_piece_to_int(board.piece_on(chess_move.get_source()));
296+
297+
let mut is_attacked: bool = true;
298+
if match_piece_to_int(board.piece_on(chess_move.get_dest())) == 6 {
299+
is_attacked = false;
300+
}
301+
let attacked_piece_type: usize = match_piece_to_int(board.piece_on(chess_move.get_dest()));
302+
303+
if board.side_to_move() == Color::White {
304+
let color_bitboard: &BitBoard = &board.color_combined(Color::White);
305+
if white_incremental_psqt_eval == 0. {
306+
white_incremental_psqt_eval += calc_increment_all(board, color_bitboard, material_each_side)
307+
} else {
308+
309+
//Remove the eval from the previous square we stood on.
310+
let source: usize = (56 - chess_move.get_source().to_int() + 2*(chess_move.get_source().to_int() % 8)) as usize;
311+
white_incremental_psqt_eval -= calc_increment(moved_piece_type, source, material_each_side);
312+
313+
//Increase the eval at the destination
314+
let dest: usize = (56 - chess_move.get_dest().to_int() + 2*(chess_move.get_dest().to_int() % 8)) as usize;
315+
white_incremental_psqt_eval += calc_increment(moved_piece_type, dest, material_each_side);
316+
317+
//Decrement enemy eval from potetntial capture
318+
if is_attacked {
319+
black_incremental_psqt_eval -= calc_increment(attacked_piece_type, dest, material_each_side);
320+
}
321+
}
322+
} else {
323+
let color_bitboard: &BitBoard = &board.color_combined(Color::Black);
324+
if black_incremental_psqt_eval == 0. {
325+
black_incremental_psqt_eval += calc_increment_all(board, color_bitboard, material_each_side)
326+
} else {
327+
//Remove the eval from the previous square we stood on.
328+
let source: usize = (56 - chess_move.get_source().to_int() + 2*(chess_move.get_source().to_int() % 8)) as usize;
329+
black_incremental_psqt_eval -= calc_increment(moved_piece_type, source, material_each_side);
330+
331+
//Increase the eval at the destination
332+
let dest: usize = (56 - chess_move.get_dest().to_int() + 2*(chess_move.get_dest().to_int() % 8)) as usize;
333+
black_incremental_psqt_eval += calc_increment(moved_piece_type, dest, material_each_side);
334+
335+
//Decrement enemy eval from potetntial capture
336+
if is_attacked {
337+
white_incremental_psqt_eval -= calc_increment(attacked_piece_type, dest, material_each_side);
338+
}
339+
}
340+
}
341+
}
342+
best_evaluation.white_incremental_psqt_eval = Some(white_incremental_psqt_eval);
343+
best_evaluation.black_incremental_psqt_eval = Some(black_incremental_psqt_eval);
235344
}
236345

237346
if module_enabled(self.modules, TRANSPOSITION_TABLE) && depth >= 3 {
@@ -273,6 +382,8 @@ impl Algorithm {
273382
&mut stats,
274383
0,
275384
&mut HashMap::new(),
385+
0.,
386+
0.
276387
);
277388
let analyzer_data = out.debug_data.unwrap_or_default();
278389
(out.next_action, analyzer_data, stats)
@@ -331,9 +442,7 @@ impl Algorithm {
331442
}
332443
self.board_played_times.insert(new_board, old_value + 1);
333444

334-
if utils::module_enabled(self.modules, modules::TAPERED_INCREMENTAL_PESTO_PSQT) {
335-
336-
}
445+
337446
}
338447

339448
(action, deepest_complete_output.1, deepest_complete_output.2)
@@ -343,8 +452,7 @@ impl Algorithm {
343452
&mut self,
344453
board: &Board,
345454
board_played_times_prediction: &HashMap<Board, u32>,
346-
incremental_eval: f32,
347-
) -> f32 {
455+
) -> f32 {
348456
let board_status = board.status();
349457
if board_status == BoardStatus::Stalemate {
350458
return 0.;
@@ -417,34 +525,35 @@ impl Algorithm {
417525

418526
let mut tapered_pesto: f32 = 0.;
419527
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 {
528+
fn tapered_psqt_calc(piece_bitboard: &BitBoard, color_bitboard: &BitBoard, material: (u32, u32), piece_index: usize) -> f32 {
421529
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with NAIVE_PSQT bonus constants.
422530
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.
531+
//Get's the bitboard with all piece positions, and runs bitwise and for the board having one's own colors.
532+
//Iterates over all 64 squares on the board.
424533
for i in 0..63 {
425534
//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.
535+
//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.
427536
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;
537+
((material.0 + material.1 - 2000) as f32 * TAPERED_MG_PESTO[piece_index][i] + (material.0 + material.1 - 2000 + 78) as f32 * TAPERED_EG_PESTO[piece_index][i]) as f32;
429538
}
430-
return bonus;
539+
return bonus / 78.;
431540
}
432541

433-
if board.side_to_move() == Color::White {
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);
440-
} else {
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);
447-
}
542+
if board.side_to_move() == Color::White {
543+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Pawn), board.color_combined(Color::White), material_each_side, 0);
544+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Rook), board.color_combined(Color::White), material_each_side, 3);
545+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::King), board.color_combined(Color::White), material_each_side, 5);
546+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Queen), board.color_combined(Color::White), material_each_side, 4);
547+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Bishop), board.color_combined(Color::White), material_each_side, 2);
548+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Knight), board.color_combined(Color::White), material_each_side, 1);
549+
} else {
550+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Pawn), board.color_combined(Color::Black), material_each_side, 0);
551+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Rook), board.color_combined(Color::Black), material_each_side, 3);
552+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::King), board.color_combined(Color::Black), material_each_side, 5);
553+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Queen), board.color_combined(Color::Black), material_each_side, 4);
554+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Bishop), board.color_combined(Color::Black), material_each_side, 2);
555+
tapered_pesto += tapered_psqt_calc(board.pieces(Piece::Knight), board.color_combined(Color::Black), material_each_side, 1);
556+
}
448557
}
449558

450559
let mut pawn_structure: f32 = 0.;

src/algorithms/utils.rs

+6
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,24 @@ pub(super) struct Evaluation {
2222
pub(super) debug_data: Option<Vec<String>>,
2323
pub(super) eval: Option<f32>,
2424
pub(super) next_action: Option<Action>,
25+
pub(super) white_incremental_psqt_eval: Option<f32>,
26+
pub(super) black_incremental_psqt_eval: Option<f32>,
2527
}
2628

2729
impl Evaluation {
2830
pub(super) fn new(
2931
eval: Option<f32>,
3032
next_action: Option<Action>,
3133
debug_data: Option<Vec<String>>,
34+
white_incremental_psqt_eval: Option<f32>,
35+
black_incremental_psqt_eval: Option<f32>,
3236
) -> Evaluation {
3337
Evaluation {
3438
eval,
3539
next_action,
3640
debug_data,
41+
white_incremental_psqt_eval,
42+
black_incremental_psqt_eval
3743
}
3844
}
3945
}

0 commit comments

Comments
 (0)