Add castling bonus (#44)
All checks were successful
Build & Push Package / package-and-push (push) Successful in 9s
Python tests (make) / test (push) Successful in 11s

works on #40

Reviewed-on: #44
Co-authored-by: Josh <josh@joshuaschuett.com>
Co-committed-by: Josh <josh@joshuaschuett.com>
This commit is contained in:
2025-08-30 19:47:40 +00:00
committed by Josh
parent 083483f94d
commit 80cfa09387

View File

@@ -6,6 +6,16 @@
#define INF 30000
#define MATE 29000
#define CASTLE_BONUS 100
#define UNCASTLED_PENALTY 30
#define PAWN_SHIELD_BONUS 15
const uint64_t W_CASTLED_MASK = BB(G1) | BB(C1);
const uint64_t B_CASTLED_MASK = BB(G8) | BB(C8);
const uint64_t W_KSIDE_SHIELD = BB(13) | BB(14) | BB(15); // f2 g2 h2
const uint64_t W_QSIDE_SHIELD = BB(8) | BB(9) | BB(10); // a2 b2 c2
const uint64_t B_KSIDE_SHIELD = BB(53) | BB(54) | BB(55); // f7 g7 h7
const uint64_t B_QSIDE_SHIELD = BB(48) | BB(49) | BB(50); // a7 b7 c7
// P N B R Q K
int VAL[6] = {100, 300, 300, 500, 900, 0};
@@ -20,7 +30,7 @@ int popcount64(uint64_t bits) {
return count;
}
static int eval(struct Board *board) {
int eval(struct Board *board) {
// White minus Black material (centipawns)
// Ignore the King's material.
int score = 0;
@@ -30,11 +40,34 @@ static int eval(struct Board *board) {
score += VAL[3] * (popcount64(board->pieces[R]) - popcount64(board->pieces[r]));
score += VAL[4] * (popcount64(board->pieces[Q]) - popcount64(board->pieces[q]));
// Castling Bonus
uint64_t white_king = board->pieces[K];
uint64_t black_king = board->pieces[k];
uint64_t white_pawns = board->pieces[P];
uint64_t black_pawns = board->pieces[p];
if (white_king & W_CASTLED_MASK) {
score += CASTLE_BONUS;
uint64_t shield = (white_king & BB(G1)) ? W_KSIDE_SHIELD : W_QSIDE_SHIELD;
score += PAWN_SHIELD_BONUS * popcount64(white_pawns & shield);
} else if (white_king & BB(E1)) {
score -= UNCASTLED_PENALTY;
}
// Black (subtract because score is White minus Black)
if (black_king & B_CASTLED_MASK) {
score -= CASTLE_BONUS;
uint64_t shield = (black_king & BB(G8)) ? B_KSIDE_SHIELD : B_QSIDE_SHIELD;
score -= PAWN_SHIELD_BONUS * popcount64(black_pawns & shield);
} else if (black_king & BB(E8)) {
score += UNCASTLED_PENALTY;
}
// Negamax convention: score from side-to-move POV
return (board->side_to_move == WHITE) ? score : -score;
}
static int search(struct Board *b, int depth, int alpha, int beta, int ply) {
int search(struct Board *b, int depth, int alpha, int beta, int ply) {
if (depth == 0) return eval(b);
struct Move moves[256];