Skip to content

Commit aa85106

Browse files
committed
Several bugs fixed
1 parent d877e96 commit aa85106

File tree

4 files changed

+51
-52
lines changed

4 files changed

+51
-52
lines changed

src/algorithms/the_algorithm.rs

+19-46
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::{collections::HashMap, cmp};
22
use tokio::time::{Duration, Instant};
33

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

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

99
use super::utils::{Evaluation, TranspositionEntry};
1010

@@ -69,10 +69,11 @@ impl Algorithm {
6969
// stats.time_for_transposition_access += Instant::now() - start;
7070
// stats.transposition_table_entries += 1
7171
// }
72-
let incremental_psqt_eval = white_incremental_psqt_eval;
72+
let mut incremental_psqt_eval: f32 = white_incremental_psqt_eval;
7373
if board.side_to_move() == Color::Black {
74-
let incremental_psqt_eval = black_incremental_psqt_eval;
75-
}
74+
incremental_psqt_eval = black_incremental_psqt_eval;
75+
}
76+
7677
return Evaluation::new(Some(eval + incremental_psqt_eval), None, None, Some(white_incremental_psqt_eval), Some(black_incremental_psqt_eval));
7778
}
7879

@@ -243,37 +244,9 @@ impl Algorithm {
243244
}
244245

245246
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-
274247
let material_each_side = utils::material_each_side(board);
275248
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;
249+
return ((material_each_side.0 + material_each_side.1 - 2000) as f32 * TAPERED_MG_PESTO[piece_type][location] + (2000 + 78 - material_each_side.0 - material_each_side.1) as f32 * TAPERED_EG_PESTO[piece_type][location]) as f32 / 78.;
277250
}
278251

279252
fn calc_increment_all(board: &Board, color_bitboard: &BitBoard, material_each_side: (u32, u32)) -> f32 {
@@ -286,8 +259,8 @@ impl Algorithm {
286259
for i in 0..63 {
287260
//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).
288261
//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.;
262+
incremental_psqt_eval += ((board.pieces(match_int_to_piece(j)) & color_bitboard).reverse_colors().to_size(i as u8) & 1) as f32 *
263+
((material_each_side.0 + material_each_side.1 - 2000) as f32 * TAPERED_MG_PESTO[j as usize][i as usize] + (2000 + 78 - material_each_side.0 - material_each_side.1) as f32 * TAPERED_EG_PESTO[j as usize][i as usize]) as f32 / 78.;
291264
}
292265
}
293266
return incremental_psqt_eval;
@@ -470,10 +443,10 @@ impl Algorithm {
470443
// This is third time this is played. Draw by three-fold repetition
471444
return 0.;
472445
}
473-
let material_each_side = utils::material_each_side(board);
446+
let material_each_side: (u32, u32) = utils::material_each_side(board);
474447

475448
// Negative when black has advantage
476-
let diff_material = material_each_side.0 as i32 - material_each_side.1 as i32;
449+
let diff_material: i32 = material_each_side.0 as i32 - material_each_side.1 as i32;
477450

478451
let mut controlled_squares = 0;
479452
if utils::module_enabled(self.modules, modules::SQUARE_CONTROL_METRIC) {
@@ -526,17 +499,17 @@ impl Algorithm {
526499
let mut tapered_pesto: f32 = 0.;
527500
if utils::module_enabled(self.modules, modules::TAPERED_EVERY_PRESTO_PSQT) {
528501
fn tapered_psqt_calc(piece_bitboard: &BitBoard, color_bitboard: &BitBoard, material: (u32, u32), piece_index: usize) -> f32 {
529-
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with NAIVE_PSQT bonus constants.
502+
//Essentially, gets the dot product between a "vector" of the bitboard (containing 64 0s and 1s) and the table with TAPERED_PRESTO_PSQT bonus constants.
530503
let mut bonus: f32 = 0.;
531504
//Get's the bitboard with all piece positions, and runs bitwise and for the board having one's own colors.
532505
//Iterates over all 64 squares on the board.
533506
for i in 0..63 {
534507
//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).
535508
//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.
536-
bonus += ((piece_bitboard & color_bitboard).reverse_colors().to_size(0) >> i & 1) 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;
509+
bonus += ((piece_bitboard & color_bitboard).reverse_colors().to_size(i) & 1) as f32 *
510+
((material.0 + material.1 - 2000) as f32 * TAPERED_MG_PESTO[piece_index][i as usize] + (2000 + 78 - material.0 - material.1) as f32 * TAPERED_EG_PESTO[piece_index][i as usize]) as f32;
538511
}
539-
return bonus / 78.;
512+
return bonus;
540513
}
541514

542515
if board.side_to_move() == Color::White {
@@ -562,16 +535,16 @@ impl Algorithm {
562535
let mut bonus: f32 = 0.;
563536
let pawn_bitboard: usize = (all_pawn_bitboard & color_bitboard).to_size(0);
564537
let king_bitboard: usize = (all_king_bitboard & color_bitboard).to_size(0);
565-
//pawn chain, awarding 0.5 eval for each pawn protected by another pawn.
566-
bonus += 0.5*((pawn_bitboard & (pawn_bitboard << 7)).count_ones() + (pawn_bitboard & (pawn_bitboard << 9)).count_ones()) as f32;
538+
//pawn chain, awarding 0.5 eval for each pawn protected by another pawn. Constants should in theory cover an (literal) edge case... I hope.
539+
bonus += 0.5*((pawn_bitboard & (0xFEFEFEFEFEFEFEFE & pawn_bitboard << 7)).count_ones() + (pawn_bitboard & (0x7F7F7F7F7F7F7F7F & pawn_bitboard << 9)).count_ones()) as f32;
567540

568541
//stacked pawns. -0.5 points per rank containing >1 pawns. By taking the pawn bitboard and operating bitwise AND for another bitboard (integer) where the leftmost rank is filled. This returns all pawns in that rank. By bitshifting we can choose rank. Additionally by counting we get number of pawns. We then remove 1 as we only want to know if there are >1 pawn. If there is, subtract 0.5 points per extra pawn.
569542
for i in 0..7 {
570543
//constant 9259542123273814144 = 0x8080808080808080, or the entire first rank.
571544
bonus -= 0.5*cmp::max((pawn_bitboard & (0x8080808080808080 >> i)).count_ones() as i64 - 1, 0) as f32;
572545
}
573546

574-
//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.
547+
//king safety. Outer 3 pawns get +1 eval bonus per pawn if king is behind them. King position required is either ..X..... or ......X.
575548
bonus += ((king_bitboard & 0x2).count_ones() * (pawn_bitboard & 0x107).count_ones() + (king_bitboard & 0x20).count_ones() * (pawn_bitboard & 0x80E000).count_ones()) as f32;
576549
return bonus;
577550
}
@@ -592,7 +565,7 @@ impl Algorithm {
592565
}
593566
}
594567

595-
let evaluation: f32 = controlled_squares as f32 / 20. + diff_material as f32 + naive_psqt + pawn_structure + tapered_pesto;
568+
let evaluation: f32 = controlled_squares as f32 / 20. + diff_material as f32 + naive_psqt + pawn_structure + tapered_pesto/78.;
596569
return evaluation
597570
}
598571

src/common/constants.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub(crate) mod modules {
88
pub(crate) const NAIVE_PSQT: u32 = 0b1000000;
99
pub(crate) const PAWN_STRUCTURE: u32 = 0b10000000;
1010
pub(crate) const TAPERED_EVERY_PRESTO_PSQT: u32 = 0b100000000;
11-
pub(crate) const TAPERED_INCREMENTAL_PESTO_PSQT: u32 = 0b100000000;
11+
pub(crate) const TAPERED_INCREMENTAL_PESTO_PSQT: u32 = 0b1000000000;
1212
}
1313

1414
//NAIVE_PSQT TABLES

src/common/utils.rs

+26
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,29 @@ pub(crate) fn passed_deadline(deadline: Instant) -> bool {
155155
pub(crate) fn module_enabled(modules: u32, module_to_test: u32) -> bool {
156156
modules & module_to_test != 0
157157
}
158+
159+
pub(crate) fn match_piece_to_int(input: Option<Piece>) -> usize {
160+
match input {
161+
Some(Piece::Pawn) => 0,
162+
Some(Piece::Knight) => 1,
163+
Some(Piece::Bishop) => 2,
164+
Some(Piece::Rook) => 3,
165+
Some(Piece::Queen) => 4,
166+
Some(Piece::King) => 5,
167+
//Note: Returning a 6 is not intended, and must be handled on a case-by-case basis.
168+
None => 6
169+
}
170+
}
171+
172+
pub(crate) fn match_int_to_piece(input: u8) -> Piece {
173+
match input {
174+
0 => Piece::Pawn,
175+
1 => Piece::Knight,
176+
2 => Piece::Bishop,
177+
3 => Piece::Rook,
178+
4 => Piece::Queen,
179+
5 => Piece::King,
180+
//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!
181+
6_u8..=u8::MAX => unimplemented!()
182+
}
183+
}

src/main.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::time::Duration;
22

33
use crate::algorithms::the_algorithm::Algorithm;
4-
#[allow(dead_code, unused_imports)]
4+
#[allow(unused_imports)]
55
use crate::common::constants::modules::{
66
ALPHA_BETA, ANALYZE, SEARCH_EXTENSIONS, SKIP_BAD_MOVES, SQUARE_CONTROL_METRIC,
77
TRANSPOSITION_TABLE, NAIVE_PSQT, PAWN_STRUCTURE, TAPERED_EVERY_PRESTO_PSQT, TAPERED_INCREMENTAL_PESTO_PSQT
88
};
99

10-
use self::pitter::logic::{Competition, GameOutcome};
10+
use self::pitter::logic::Competition;
1111

1212
mod algorithms;
1313
mod common;
@@ -16,8 +16,8 @@ mod pitter;
1616
#[tokio::main]
1717
async fn main() {
1818
//ALPHA_BETA | ANALYZE | SEARCH_EXTENSIONS | SKIP_BAD_MOVES | SQUARE_CONTROL_METRIC | TRANSPOSITION_TABLE | NAIVE_PSQT | PAWN_STRUCTURE | TAPERED_EVERY_PRESTO_PSQT | TAPERED_INCREMENTAL_PESTO_PSQT
19-
let modules1 = ALPHA_BETA | NAIVE_PSQT;
20-
let modules2 = ALPHA_BETA;
19+
let modules1 = ALPHA_BETA | TAPERED_EVERY_PRESTO_PSQT;
20+
let modules2 = ALPHA_BETA | NAIVE_PSQT;
2121
let time_per_move1 = Duration::from_micros(2000);
2222
let time_per_move2 = Duration::from_micros(2000);
2323

@@ -29,6 +29,6 @@ async fn main() {
2929
// competition.analyze_algorithm_choices(|(game_info, _), _| {
3030
// game_info.outcome == GameOutcome::InconclusiveTooLong
3131
// });
32-
let results = competition.start_competition(100).await;
32+
let results = competition.start_competition(5000).await;
3333
dbg!(results);
3434
}

0 commit comments

Comments
 (0)