From a550620aa894e218a738b62b9ecd042b03f7858f Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 31 Jul 2026 12:11:58 +0200 Subject: changes --- src/evaluate.cpp | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/evaluate.cpp (limited to 'src/evaluate.cpp') diff --git a/src/evaluate.cpp b/src/evaluate.cpp new file mode 100644 index 0000000..c53e64e --- /dev/null +++ b/src/evaluate.cpp @@ -0,0 +1,189 @@ +#include "evaluate.hpp" +#include "moves.hpp" +#include + +constexpr int PAWN_VALUE = 100; +constexpr int KNIGHT_VALUE = 320; +constexpr int BISHOP_VALUE = 400; +constexpr int ROOK_VALUE = 500; +constexpr int QUEEN_VALUE = 900; +constexpr int MATE = 10000; + +static int PAWN_TABLE[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, // last rank promotes to a quuen + 50, 50, 50, 50, 50, 50, 50, 50, // comments to stop formating to ruin it + 10, 10, 20, 35, 35, 20, 10, 10, // + 5, 5, 10, 30, 30, 10, 5, 5, // + 0, 0, 0, 25, 25, 0, 0, 0, // + 5, -5, -10, 0, 0, -10, -5, 5, // + 5, 10, 10, -20, -20, 10, 10, 5, // + 0, 0, 0, 0, 0, 0, 0, 0 // +}; + +static int KNIGHT_TABLE[64] = { + -50, -40, -30, -30, -30, -30, -40, -50, // + -40, -20, 0, 0, 0, 0, -20, -40, // + -30, 0, 10, 15, 15, 10, 0, -30, // + -30, 5, 15, 20, 20, 15, 5, -30, // + -30, 0, 15, 20, 20, 15, 0, -30, // + -30, 5, 10, 15, 15, 10, 5, -30, // + -40, -20, 0, 5, 5, 0, -20, -40, // + -50, -40, -30, -30, -30, -30, -40, -50, // +}; + +static int BISHOP_TABLE[64] = { + -20, -10, -10, -10, -10, -10, -10, -20, // + -10, 5, 0, 0, 0, 0, 5, -10, // + -10, 10, 10, 10, 10, 10, 10, -10, // + -10, 0, 10, 15, 15, 10, 0, -10, // + -10, 5, 5, 10, 10, 5, 5, -10, // + -10, 0, 5, 10, 10, 5, 0, -10, // + -10, 0, 0, 0, 0, 0, 0, -10, // + -20, -10, -10, -10, -10, -10, -10, -20, // +}; + +static int ROOK_TABLE[64] = { + 0, 0, 5, 10, 10, 5, 0, 0, // + 5, 10, 10, 10, 10, 10, 10, 5, // + -5, 0, 0, 0, 0, 0, 0, -5, // + -5, 0, 0, 5, 5, 0, 0, -5, // + -5, 0, 0, 5, 5, 0, 0, -5, // + -5, 0, 0, 0, 0, 0, 0, -5, // + 5, 10, 10, 10, 10, 10, 10, 5, // + 0, 0, 5, 10, 10, 5, 0, 0, // +}; + +static int QUEEN_TABLE[64] = { + -20, -10, -10, -5, -5, -10, -10, -20, // + -10, 0, 0, 0, 0, 0, 0, -10, // + -10, 0, 5, 5, 5, 5, 0, -10, // + -5, 0, 5, 5, 5, 5, 0, -5, // + 0, 0, 5, 5, 5, 5, 0, -5, // + -10, 5, 5, 5, 5, 5, 0, -10, // + -10, 0, 5, 0, 0, 0, 0, -10, // + -20, -10, -10, -5, -5, -10, -10, -20, // +}; + +static int KING_TABLE_EARLY[64] = { + -30, -40, -40, -50, -50, -40, -40, -30, // + -30, -40, -40, -50, -50, -40, -40, -30, // + -30, -40, -40, -50, -50, -40, -40, -30, // + -30, -40, -40, -50, -50, -40, -40, -30, // + -20, -30, -30, -40, -40, -30, -30, -20, // + -10, -20, -20, -20, -20, -20, -20, -10, // + 20, 20, 0, 0, 0, 0, 20, 20, // + 20, 30, 10, 0, 0, 10, 30, 20, // +}; + +/* + * i cound some up with better name + * this function just takes square and if color is black rotate it + */ +static int RotateBoardForBlack(const int square, const bool color) { + return color ? square : (56 ^ square); +} + +static int ForceKingToEdgeBonus(const Position enemyKing, + const Position myKing) { + int bonus = 0; + + // Push enemy king toward edge + const int distToCenter = + std::abs(enemyKing.file - 3) + std::abs(enemyKing.rank - 3); + + bonus += distToCenter * 10; + + // Bring own king closer + const int kingDistance = std::abs(myKing.file - enemyKing.file) + + std::abs(myKing.rank - enemyKing.rank); + + bonus += (14 - kingDistance) * 5; + + return bonus; +} + +static bool IsEndgame(Game *g) { + int queens = 0; + int rooks = 0; + + for (const Piece &piece : g->pieces) { + switch (piece.type) { + case QUEEN: + queens++; + break; + case ROOK: + rooks++; + break; + default: + break; + } + } + + return queens == 0 || (queens == 2 && rooks <= 1); +} + +int EvaluateBoardForWhite(Game *g) { + switch (GetNewGameState(g)) { + case WHITE_WON: + return MATE; + case BLACK_WON: + return -MATE; + case DRAW: + return 0; + case TURN: + break; + } + + int score = 0; + + for (int i = 0; i < 64; i++) { + const Piece piece = g->pieces[i]; + if (piece.type == NONEPIECE) + continue; + + int value = 0; + + switch (piece.type) { + case PAWN: + value = PAWN_VALUE; + value += PAWN_TABLE[RotateBoardForBlack(i, piece.color)]; + break; + case KNIGHT: + value = KNIGHT_VALUE; + value += KNIGHT_TABLE[RotateBoardForBlack(i, piece.color)]; + break; + case BISHOP: + value = BISHOP_VALUE; + value += BISHOP_TABLE[RotateBoardForBlack(i, piece.color)]; + break; + case ROOK: + value = ROOK_VALUE; + value += ROOK_TABLE[RotateBoardForBlack(i, piece.color)]; + break; + case QUEEN: + value = QUEEN_VALUE; + value += QUEEN_TABLE[RotateBoardForBlack(i, piece.color)]; + break; + case KING: + value = KING_TABLE_EARLY[RotateBoardForBlack(i, piece.color)]; + break; + default: + break; + } + + if (piece.color) { + score += value; + } else { + score -= value; + } + } + + Position whiteKing = FindKing(g, true); + Position blackKing = FindKing(g, false); + + if (IsEndgame(g)) { + score += ForceKingToEdgeBonus(blackKing, whiteKing); + score -= ForceKingToEdgeBonus(whiteKing, blackKing); + } + return score; +} -- cgit v1.2.3