testsAndMisc/C/lichess_random_engine/search.c
Krzysztof kuhy Rudnicki f6b6995b0e Add tests and fix pre-commit issues across all projects
- C/lichess_random_engine, vocabulary_curve, misc/split,
  1dvelocitysimulator, opening_learner: test suites added
- CPP/miscelanious: tests added
- TS/battery-status, champions_leauge_scores, two-inputs: tests added
- python_pkg/fm24_searcher, wake_alarm: new packages added
- Fix ruff/cppcheck/eslint/clang-format failures
- Update .gitignore for C/C++ build artifacts
2026-04-12 20:45:24 +02:00

107 lines
2.1 KiB
C

#include "search.h"
#include "movegen.h"
#include <limits.h>
#include <stddef.h>
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;
}