Skip to content

Commit fffda8a

Browse files
committed
Optimized lone piece logic
1 parent 2c40bc5 commit fffda8a

File tree

1 file changed

+45
-37
lines changed

1 file changed

+45
-37
lines changed

src/bot/eval.rs

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::collections::HashMap;
2-
31
use chess::{ Board, Piece };
42
use crate::bot::{ include::types::GlobalMap, util::board::BoardExt };
53

@@ -27,14 +25,6 @@ fn is_endgame(board: &Board) -> bool {
2725
non_king_material < 1600 // adjust threshold as needed
2826
}
2927

30-
fn piece_counts(pieces: &[Piece]) -> HashMap<Piece, usize> {
31-
let mut counts = HashMap::new();
32-
for &piece in pieces {
33-
*counts.entry(piece).or_insert(0) += 1;
34-
}
35-
counts
36-
}
37-
3828
pub fn evaluate_board(board: &Board) -> i32 {
3929
use chess::{ Piece::*, Color::* };
4030

@@ -48,43 +38,61 @@ pub fn evaluate_board(board: &Board) -> i32 {
4838
return if board.side_to_move() == White { -10_000 } else { 10_000 };
4939
}
5040

51-
let mut white_pieces = vec![];
52-
let mut black_pieces = vec![];
41+
let mut white_total = 0;
42+
let mut black_total = 0;
43+
let mut white_bishops = 0;
44+
let mut black_bishops = 0;
45+
let mut white_knights = 0;
46+
let mut black_knights = 0;
5347

5448
for sq in chess::ALL_SQUARES {
5549
if let Some(piece) = board.piece_on(sq) {
5650
let color = board.color_on(sq).unwrap();
57-
if color == White {
58-
white_pieces.push(piece);
59-
} else {
60-
black_pieces.push(piece);
51+
52+
match color {
53+
White => {
54+
white_total += 1;
55+
match piece {
56+
Piece::Bishop => {
57+
white_bishops += 1;
58+
}
59+
Piece::Knight => {
60+
white_knights += 1;
61+
}
62+
_ => {}
63+
}
64+
}
65+
Black => {
66+
black_total += 1;
67+
match piece {
68+
Piece::Bishop => {
69+
black_bishops += 1;
70+
}
71+
Piece::Knight => {
72+
black_knights += 1;
73+
}
74+
_ => {}
75+
}
76+
}
6177
}
6278
}
6379
}
6480

65-
let minor_or_lone = |pieces: &[Piece]| {
66-
let counts = piece_counts(pieces);
67-
68-
match counts.get(&Piece::King) {
69-
Some(&1) => {
70-
let num_bishops = *counts.get(&Piece::Bishop).unwrap_or(&0);
71-
let num_knights = *counts.get(&Piece::Knight).unwrap_or(&0);
72-
let total_pieces = pieces.len();
73-
74-
match (num_bishops, num_knights, total_pieces) {
75-
(0, 0, 1) => true, // just king
76-
(1, 0, 2) => true, // king + bishop
77-
(0, 1, 2) => true, // king + knight
78-
(0, 2, 3) => true, // king + 2 knights
79-
_ => false,
80-
}
81-
}
81+
let is_minor_or_lone = |total: usize, bishops: usize, knights: usize| {
82+
match total {
83+
1 => true, // Only king
84+
2 if bishops == 1 => true, // King + bishop
85+
2 if knights == 1 => true, // King + knight
86+
3 if knights == 2 => true, // King + 2 knights
8287
_ => false,
8388
}
8489
};
8590

86-
// Case 1: Both sides have only king/king+bishop/knight/(2 knights)
87-
if minor_or_lone(&white_pieces) && minor_or_lone(&black_pieces) {
91+
// Case 1: Both sides have only king/(bishop|knight|2 knights) → draw
92+
if
93+
is_minor_or_lone(white_total, white_bishops, white_knights) &&
94+
is_minor_or_lone(black_total, black_bishops, black_knights)
95+
{
8896
return 0;
8997
}
9098

@@ -128,11 +136,11 @@ pub fn evaluate_board(board: &Board) -> i32 {
128136
let value = base + positional;
129137

130138
if color == White {
131-
if !minor_or_lone(&white_pieces) {
139+
if !is_minor_or_lone(white_total, white_bishops, white_knights) {
132140
score += value;
133141
}
134142
} else {
135-
if !minor_or_lone(&black_pieces) {
143+
if !is_minor_or_lone(black_total, black_bishops, black_knights) {
136144
score -= value;
137145
}
138146
}

0 commit comments

Comments
 (0)