#include "search.h" #include "movegen.h" #include #include static int piece_value(Piece p) { switch (p) { case WK: case BK: return 0; /* king is invaluable; PST handled later if needed */ case WP: case BP: return 100; case WN: case BN: return 320; case WB: case BB: return 330; case WR: case BR: return 500; case WQ: case BQ: return 900; default: return 0; } } int evaluate(const Position *pos) { int score = 0; for (int sq = 0; sq < BOARD_SIZE; ++sq) { if ((sq & 0x88)) { sq = (sq | 7); continue; } Piece p = pos->board[sq]; int v = piece_value(p); if (p >= WP && p <= WK) { score += v; } else if (p >= BP && p <= BK) { score -= v; } } // Score from side-to-move perspective return (pos->side == WHITE) ? score : -score; } int alphabeta(Position pos, int depth, int alpha, int beta, PrincipalVariation *pv) { if (depth <= 0) { return evaluate(&pos); } Move moves[256]; int n = gen_moves(&pos, moves, 256, 0); if (n == 0) { // Checkmate or stalemate if (in_check(&pos, pos.side)) { return -30000 + (10 - depth); // checkmated } return 0; // stalemate } int best_score = INT_MIN / 2; int best_from = -1; int best_to = -1; for (int i = 0; i < n; i++) { Position child = pos; Piece cap = EMPTY; make_move(&child, &moves[i], &cap); int score = -alphabeta(child, depth - 1, -beta, -alpha, NULL); if (score > best_score) { best_score = score; best_from = moves[i].from; best_to = moves[i].to; } if (best_score > alpha) { alpha = best_score; } if (alpha >= beta) { break; // beta cutoff } } if (pv != NULL) { pv->from = best_from; pv->to = best_to; } return best_score; }