summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-08-19 22:01:58 +0300
committereug-vs <eugene@eug-vs.xyz>2022-08-20 14:06:24 +0300
commit98a9002bb9bef19843112366e2ab464069fcca58 (patch)
tree1bfd150701b6cf49d1e77383aae20d94cfb174d6
parent7bdcd3c4c96ecef95d4cfc4874d134d0e136171f (diff)
downloadc-chess-98a9002bb9bef19843112366e2ab464069fcca58.tar.gz
feat: compute positioning advantage
-rw-r--r--src/main.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/src/main.c b/src/main.c
index 100a80a..fe1836e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,6 +3,7 @@
#include <string.h>
#include <time.h>
#include <stdlib.h>
+#include <math.h>
#include "config.h"
#include "pieces.h"
@@ -304,6 +305,10 @@ int evaluate_pawn(int piece, int rank) {
}
}
+/*
+ * Compute material advantage of a player over an opponent
+ * Returns number in range (0, 30)
+ */
int compute_material_advantage(int* board, int color) {
int counter = 0;
for (int rank = 7; rank >= 0; rank--) {
@@ -340,6 +345,10 @@ int compute_material_advantage(int* board, int color) {
return counter;
}
+/*
+ * Calculate amount of squares attack by players pieces
+ * Returns number in range (0, 64)
+ */
int compute_coverage(int* board, int color) {
int hit_map[128];
for (int rank = 7; rank >= 0; rank--) {
@@ -402,9 +411,64 @@ int compute_coverage(int* board, int color) {
return counter;
}
+/*
+ * Compute player pieces score depending on how
+ * well they are positioned on the board
+ *
+ * Returns number in range(0, 112)
+ */
+int compute_positioning_score(int* board, int color) {
+ int total_score = 0;
+ double center = 3.5;
+
+ for (double rank = 7; rank >= 0; rank--) {
+ for (double file = 0; file < 8; file++) {
+ int index = rank * 16 + file;
+ int piece = board[index];
+ int score = 7 - (fabs(rank - center) + fabs(file - center));
+
+ int multiplier = 1;
+ switch (piece & NO_COLOR) {
+ case KNIGHT:
+ multiplier = 4;
+ break;
+ case BISHOP:
+ multiplier = 3;
+ break;
+ case PAWN:
+ multiplier = 2;
+ break;
+ case KING:
+ multiplier = -1; // Discourage king in center (encourage castle)
+ // TODO: encourage king in center after opponent has low material <= 6
+ break;
+ default:
+ multiplier = 1;
+ break;
+ }
+
+ total_score += score * multiplier;
+ }
+ }
+
+ return total_score;
+}
+
+/*
+ * Return a total board score symbolizing advantage
+ * for WHITE, meaining WHITE tries to maximize this
+ * value and BLACK tries to minimize it.
+ */
int compute_score(int* board) {
+ int material_advantage = compute_material_advantage(board, WHITE);
+
int coverage_score = compute_coverage(board, WHITE) - compute_coverage(board, BLACK);
- return compute_material_advantage(board, WHITE)* 3 + coverage_score;
+ int normalized_coverage = coverage_score / 2;
+
+ int positioning_score = compute_positioning_score(board, WHITE) - compute_positioning_score(board, BLACK);
+ int normalized_positioning = positioning_score / 7;
+
+ return material_advantage + coverage_score + positioning_score;
}
int list_available_moves(Move moves[MAX_AVAILABLE_MOVES], int* board, int color) {