Skip to content

Commit 2985a9e

Browse files
committed
Position Tables use HashMaps
By using HashMaps the Position Tables run 6.5% faster.
1 parent 074a51d commit 2985a9e

File tree

3 files changed

+52
-30
lines changed

3 files changed

+52
-30
lines changed

src/algorithms/the_algorithm.rs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ pub(crate) struct Algorithm {
1616
pub(crate) time_per_move: Duration,
1717
/// Number of times that a given board has been played
1818
pub(crate) board_played_times: HashMap<Board, u32>,
19-
pub(crate) pawn_hash: HashMap<BitBoard, f32>
19+
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>
26+
2027
}
2128

2229
impl Algorithm {
@@ -26,7 +33,13 @@ impl Algorithm {
2633
transposition_table: HashMap::with_capacity(45),
2734
time_per_move,
2835
board_played_times: HashMap::new(),
29-
pawn_hash: HashMap::new()
36+
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(),
3043
}
3144
}
3245

@@ -371,20 +384,28 @@ impl Algorithm {
371384
}
372385
return bonus;
373386
}
387+
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));
391+
}
392+
return *position_hash_map.get(&(bitboard & color_bitboard)).unwrap();
393+
}
394+
374395
if board.side_to_move() == Color::White {
375-
position_bonus += position_bonus_calc(position_bonus_table_pawn, board.pieces(Piece::Pawn), board.color_combined(Color::White));
376-
position_bonus += position_bonus_calc(position_bonus_table_knight, board.pieces(Piece::Knight), board.color_combined(Color::White));
377-
position_bonus += position_bonus_calc(position_bonus_table_rook, board.pieces(Piece::Rook), board.color_combined(Color::White));
378-
position_bonus += position_bonus_calc(position_bonus_table_king, board.pieces(Piece::King), board.color_combined(Color::White));
379-
position_bonus += position_bonus_calc(position_bonus_table_queen, board.pieces(Piece::Queen), board.color_combined(Color::White));
380-
position_bonus += position_bonus_calc(position_bonus_table_bishop, board.pieces(Piece::Bishop), board.color_combined(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);
381402
} else {
382-
position_bonus += position_bonus_calc(position_bonus_table_pawn, board.pieces(Piece::Pawn), board.color_combined(Color::Black));
383-
position_bonus += position_bonus_calc(position_bonus_table_knight, board.pieces(Piece::Knight), board.color_combined(Color::Black));
384-
position_bonus += position_bonus_calc(position_bonus_table_rook, board.pieces(Piece::Rook), board.color_combined(Color::Black));
385-
position_bonus += position_bonus_calc(position_bonus_table_king, board.pieces(Piece::King), board.color_combined(Color::Black));
386-
position_bonus += position_bonus_calc(position_bonus_table_queen, board.pieces(Piece::Queen), board.color_combined(Color::Black));
387-
position_bonus += position_bonus_calc(position_bonus_table_bishop, board.pieces(Piece::Bishop), board.color_combined(Color::Black));
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);
388409
}
389410
}
390411

@@ -397,19 +418,14 @@ impl Algorithm {
397418
//pawn chain, awarding 0.5 eval for each pawn protected by another pawn.
398419
bonus += 0.5*((pawn_bitboard & (pawn_bitboard << 7)).count_ones() + (pawn_bitboard & (pawn_bitboard << 9)).count_ones()) as f32;
399420

400-
//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
421+
//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.
401422
for i in 0..7 {
402423
//constant 9259542123273814144 = 0x8080808080808080, or the entire first rank.
403424
bonus -= 0.5*cmp::max((pawn_bitboard & (0x8080808080808080 >> i)).count_ones() as i64 - 1, 0) as f32;
404425
}
405426

406427
//king safety. Outer 3 pawns get +1 eval bonus per pawn if king is behind them. King position required is either ..X..... or ......X.
407-
if (king_bitboard & 0x2).count_ones() > 0 {
408-
bonus += (pawn_bitboard & 0x7).count_ones() as f32;
409-
}
410-
if (king_bitboard & 0x20).count_ones() > 0 {
411-
bonus += (pawn_bitboard & 0xE000).count_ones() as f32;
412-
}
428+
bonus += ((king_bitboard & 0x2).count_ones() * (pawn_bitboard & 0x7).count_ones() + (king_bitboard & 0x20).count_ones() * (pawn_bitboard & 0xE000).count_ones()) as f32;
413429
return bonus;
414430
}
415431

@@ -437,5 +453,11 @@ impl Algorithm {
437453
self.transposition_table = HashMap::new();
438454
self.board_played_times = HashMap::new();
439455
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();
440462
}
441463
}

src/common/constants.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub(crate) mod modules {
1111

1212
//POSITION_BONUS TABLES
1313
pub(crate) mod position_bonus_tables {
14-
pub(crate) const position_bonus_table_pawn: [f32; 64] = [
14+
pub(crate) const POSITION_BONUS_TABLE_PAWN: [f32; 64] = [
1515
0., 0., 0., 0., 0., 0., 0., 0.,
1616
1., 1., 1., 1., 1., 1., 1., 1.,
1717
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
@@ -22,7 +22,7 @@ pub(crate) const position_bonus_table_pawn: [f32; 64] = [
2222
0., 0., 0., 0., 0., 0., 0., 0.
2323
];
2424

25-
pub(crate) const position_bonus_table_knight: [f32; 64] = [
25+
pub(crate) const POSITION_BONUS_TABLE_KNIGHT: [f32; 64] = [
2626
0., 0., 0., 0., 0., 0., 0., 0.,
2727
0., 0., 0., 0., 0., 0., 0., 0.,
2828
0., 0., 0., 0.2, 0.2, 0., 0., 0.,
@@ -33,7 +33,7 @@ pub(crate) const position_bonus_table_knight: [f32; 64] = [
3333
0., 0., 0., 0., 0., 0., 0., 0.
3434
];
3535

36-
pub(crate) const position_bonus_table_rook: [f32; 64] = [
36+
pub(crate) const POSITION_BONUS_TABLE_ROOK: [f32; 64] = [
3737
0., 0., 0.1, 0.1, 0.1, 0.1, 0., 0.,
3838
0., 0., 0., 0., 0., 0., 0., 0.,
3939
0., 0., 0., 0., 0., 0., 0., 0.,
@@ -44,7 +44,7 @@ pub(crate) const position_bonus_table_rook: [f32; 64] = [
4444
0., 0., 0.1, 0.1, 0.1, 0.1, 0., 0.
4545
];
4646

47-
pub(crate) const position_bonus_table_bishop: [f32; 64] = [
47+
pub(crate) const POSITION_BONUS_TABLE_BISHOP: [f32; 64] = [
4848
0., 0., 0., 0., 0., 0., 0., 0.,
4949
0., 0., 0., 0., 0., 0., 0., 0.,
5050
0., 0., 0., 0., 0., 0., 0., 0.,
@@ -55,7 +55,7 @@ pub(crate) const position_bonus_table_bishop: [f32; 64] = [
5555
0., 0.05, 0., 0., 0., 0., 0.05, 0.
5656
];
5757

58-
pub(crate) const position_bonus_table_queen: [f32; 64] = [
58+
pub(crate) const POSITION_BONUS_TABLE_QUEEN: [f32; 64] = [
5959
0., 0., 0., 0., 0., 0., 0., 0.,
6060
0., 0., 0., 0., 0., 0., 0., 0.,
6161
0., 0., 0.1, 0.1, 0.1, 0.1, 0., 0.,
@@ -66,7 +66,7 @@ pub(crate) const position_bonus_table_queen: [f32; 64] = [
6666
0., 0., 0., 0., 0., 0., 0., 0.
6767
];
6868

69-
pub(crate) const position_bonus_table_king: [f32; 64] = [
69+
pub(crate) const POSITION_BONUS_TABLE_KING: [f32; 64] = [
7070
0., 0., 0., 0., 0., 0., 0., 0.,
7171
0., 0., 0., 0., 0., 0., 0., 0.,
7272
0., 0., 0., 0., 0., 0., 0., 0.,

src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ mod pitter;
1616
#[tokio::main]
1717
async fn main() {
1818
//ALPHA_BETA | ANALYZE | SEARCH_EXTENSIONS | SKIP_BAD_MOVES | SQUARE_CONTROL_METRIC | TRANSPOSITION_TABLE | POSITION_BONUS | PAWN_STRUCTURE
19-
let modules1 = ALPHA_BETA | PAWN_STRUCTURE;
19+
let modules1 = ALPHA_BETA | POSITION_BONUS;
2020
let modules2 = ALPHA_BETA;
21-
let time_per_move1 = Duration::from_micros(12000);
22-
let time_per_move2 = Duration::from_micros(12000);
21+
let time_per_move1 = Duration::from_micros(2000);
22+
let time_per_move2 = Duration::from_micros(2000);
2323

2424
let competition = Competition::new(
2525
Algorithm::new(modules1, time_per_move1),

0 commit comments

Comments
 (0)