#include "types.h" #include "help.h" #include "moves.h" #include #include #include #define PAWN_VALUE 100 #define KNIGHT_VALUE 320 #define BISHOP_VALUE 330 #define ROOK_VALUE 500 #define QUEEN_VALUE 900 #define KING_VALUE 20000 #define INF 9000000 #define MAX_DEPTH 3 int evaluateBoard(game *game); void makeMove(game *g, move* m); int negamax(game *g, int depth, int alpha, int beta, int color); move *findBest(move* moves, size_t size, game* g){ int bestScore = -INF; move *bestMove = NULL; int color = g->whiteToMove ? 1 : -1; for (int i = 0; i < size; i++) { game gg = *g; makeMove(&gg, &moves[i]); int score = -negamax(&gg, MAX_DEPTH, -INF, INF, -color); if (score > bestScore || bestScore == -INF) { bestScore = score; bestMove = &moves[i]; printf("info score cp %d\n", g->whiteToMove ? bestScore : -bestScore); } } return bestMove; } int evaluateBoard(game *game) { int score = 0; score += __builtin_popcountll(game->white.pawns) * PAWN_VALUE; score += __builtin_popcountll(game->white.knights) * KNIGHT_VALUE; score += __builtin_popcountll(game->white.bishops) * BISHOP_VALUE; score += __builtin_popcountll(game->white.rooks) * ROOK_VALUE; score += __builtin_popcountll(game->white.queen) * QUEEN_VALUE; score += __builtin_popcountll(game->white.king) * KING_VALUE; score -= __builtin_popcountll(game->black.pawns) * PAWN_VALUE; score -= __builtin_popcountll(game->black.knights) * KNIGHT_VALUE; score -= __builtin_popcountll(game->black.bishops) * BISHOP_VALUE; score -= __builtin_popcountll(game->black.rooks) * ROOK_VALUE; score -= __builtin_popcountll(game->black.queen) * QUEEN_VALUE; score -= __builtin_popcountll(game->black.king) * KING_VALUE; return score; } void makeMove(game *g, move* m) { unsigned long long from_bit = 1ULL << m->From; unsigned long long to_bit = 1ULL << m->To; unsigned long long *set = findSet(g, from_bit); if (!set) return; *set &= ~from_bit; unsigned long long *captured = findSet(g, to_bit); if (captured) *captured &= ~to_bit; if (m->Promo) { char promoChar = g->whiteToMove ? toupper(m->Promo) : m->Promo; unsigned long long *newSet = charToSet(g, promoChar); if (newSet) *newSet |= to_bit; } else { *set |= to_bit; } g->whiteToMove = !g->whiteToMove; } int negamax(game *g, int depth, int alpha, int beta, int color) { if (depth == 0) return color * evaluateBoard(g); move moves[1500]; int cnt = pawnMove(g, moves); cnt += knightMove(g, moves + cnt); cnt += rookMove(g, moves + cnt); cnt += bishopMove(g, moves + cnt); cnt += kingMove(g, moves + cnt); cnt += queenMove(g, moves + cnt); if (cnt == 0) return 0; int bestValue = -INF; for (int i = 0; i < cnt; i++) { game gg = *g; makeMove(&gg, &moves[i]); int value = -negamax(&gg, depth - 1, -beta, -alpha, -color); if (value > bestValue) bestValue = value; if (value > alpha) alpha = value; if (alpha >= beta) break; } return bestValue; }