commit 2274b78c09de2543b93aa6b439ca7440c278e651
parent 311aab31f8f60a6b274b50c3e26e7ad2208c3675
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Tue, 8 Aug 2023 14:19:02 +0200
Shuffle the stats around
Diffstat:
5 files changed, 126 insertions(+), 109 deletions(-)
diff --git a/src/engine/engine.c b/src/engine/engine.c
@@ -8,40 +8,21 @@
#include "moves.h"
#include "perft.h"
#include "score.h"
+#include "stats.h"
#include "transposition.h"
#include "utils.h"
#include "zobrist.h"
#include <cul/assert.h>
#include <cul/mem.h>
+#include <cul/utils.h>
-#define MAX_PLY 64
#define FULL_DEPTH 4
#define REDUCTION_LIMIT 3
#define REDUCTION_MOVE 2
#define WINDOW 50
-typedef struct Stats Stats;
-struct Stats {
- Move pv_table[MAX_PLY][MAX_PLY];
- Move killer_moves[2][MAX_PLY];
- U32 history_moves[16][64];
- TTable *ttable;
- long nodes;
- int ply;
- int pv_length[MAX_PLY];
- int follow_pv, score_pv;
-};
-
-Stats *Stats_new(void) {
- Stats *p;
- NEW0(p);
- return p;
-}
-
-void Stats_free(Stats **p) { FREE(*p); }
-
int move_score(Stats *stats, Move move) {
if (stats->score_pv) {
if (move_cmp(stats->pv_table[0][stats->ply], move)) {
@@ -113,28 +94,50 @@ int evaluate(const Board *board) {
return score;
}
-int quiescence(Stats *stats, const Board *board, int alpha, int beta) {
+int is_repetition() { return 0; }
+
+int stats_move_make(Stats *self, Board *copy, Move move, int flag) {
+ board_copy(self->board, copy);
+ if (!move_make(move, self->board, flag)) {
+ board_copy(copy, self->board);
+ return 0;
+ }
+ self->ply++;
+ return 1;
+}
+
+void stats_move_make_pruning(Stats *self, Board *copy) {
+ board_copy(self->board, copy);
+ board_side_switch(self->board);
+ board_enpassant_set(self->board, no_sq);
+ self->ply++;
+}
+
+void stats_move_unmake(Stats *self, Board *copy) {
+ board_copy(copy, self->board);
+ self->ply--;
+}
+
+int quiescence(Stats *stats, int alpha, int beta) {
stats->nodes++;
- int score = evaluate(board);
+ int score = evaluate(stats->board);
if (score >= beta) return beta;
if (score > alpha) alpha = score;
if (stats->ply > MAX_PLY - 1) return score;
Board copy;
+
MoveList moves;
- move_list_generate(&moves, board);
+ move_list_generate(&moves, stats->board);
move_list_sort(stats, &moves);
for (int i = 0; i < move_list_size(&moves); i++) {
- board_copy(board, ©);
Move move = move_list_move(&moves, i);
- if (move_make(move, ©, 1) == 0) continue;
-
- stats->ply++;
- score = -quiescence(stats, ©, -beta, -alpha);
- stats->ply--;
+ if (!stats_move_make(stats, ©, move, 1)) continue;
+ score = -quiescence(stats, -beta, -alpha);
+ stats_move_unmake(stats, ©);
if (score > alpha) {
alpha = score;
@@ -145,52 +148,42 @@ int quiescence(Stats *stats, const Board *board, int alpha, int beta) {
return alpha;
}
-int is_repetition() { return 0; }
-
-int negamax(Stats *stats, const Board *board, int alpha, int beta, int depth) {
- U64 bhash = board_hash(board);
+int negamax(Stats *stats, int alpha, int beta, int depth) {
+ int pv_node = (beta - alpha) > 1;
HasheFlag flag = flagAlpha;
+ Move bestMove = {0};
+ Board copy;
- if (stats->ply && is_repetition()) return 0;
+ stats->pv_length[stats->ply] = stats->ply;
- int pv_node = (beta - alpha) > 1;
- int score =
- ttable_read(stats->ttable, bhash, alpha, beta, depth, stats->ply);
+ int score = ttable_read(stats, alpha, beta, depth);
if (stats->ply && score != TTABLE_UNKNOWN && !pv_node) return score;
- stats->pv_length[stats->ply] = stats->ply;
+ if (stats->ply && is_repetition()) return 0;
if (depth == 0) {
- int score = quiescence(stats, board, alpha, beta);
- ttable_write(stats->ttable, bhash, score, depth, stats->ply, flagExact);
+ int score = quiescence(stats, alpha, beta);
+ ttable_write(stats, score, depth, flagExact);
return score;
}
if (alpha < -MATE_VALUE) alpha = -MATE_VALUE;
if (beta > MATE_VALUE - 1) beta = MATE_VALUE - 1;
if (alpha >= beta) return alpha;
- if (stats->ply > MAX_PLY - 1) return evaluate(board);
+ if (stats->ply > MAX_PLY - 1) return evaluate(stats->board);
stats->nodes++;
- int isCheck = board_isCheck(board);
+ int isCheck = board_isCheck(stats->board);
if (isCheck) depth++;
- Board copy;
-
if (depth >= 3 && !isCheck && stats->ply) {
- board_copy(board, ©);
- board_side_switch(©);
- board_enpassant_set(©, no_sq);
-
- stats->ply++;
- score = -negamax(stats, ©, -beta, -beta + 1,
- depth - 1 - REDUCTION_MOVE);
- stats->ply--;
-
+ stats_move_make_pruning(stats, ©);
+ score = -negamax(stats, -beta, -beta + 1, depth - 1 - REDUCTION_MOVE);
+ stats_move_unmake(stats, ©);
if (score >= beta) return beta;
}
MoveList list;
- move_list_generate(&list, board);
+ move_list_generate(&list, stats->board);
if (stats->follow_pv) enable_pv_scoring(stats, &list);
move_list_sort(stats, &list);
@@ -198,35 +191,30 @@ int negamax(Stats *stats, const Board *board, int alpha, int beta, int depth) {
int searched = 0;
for (int i = 0; i < move_list_size(&list); i++) {
const Move move = move_list_move(&list, i);
-
- board_copy(board, ©);
- if (move_make(move, ©, 0) == 0) continue;
+ if (!stats_move_make(stats, ©, move, 0)) continue;
legal_moves++;
- stats->ply++;
-
- int score;
if (!searched) {
- score = -negamax(stats, ©, -beta, -alpha, depth - 1);
+ score = -negamax(stats, -beta, -alpha, depth - 1);
} else {
// Late Move Reduction
if (searched >= FULL_DEPTH && depth >= REDUCTION_LIMIT &&
!isCheck && !move_capture(move) && !move_promote(move)) {
- score = -negamax(stats, ©, -alpha - 1, -alpha, depth - 2);
+ score = -negamax(stats, -alpha - 1, -alpha, depth - 2);
} else
score = alpha + 1;
// found better move
if (score > alpha) {
- score = -negamax(stats, ©, -alpha - 1, -alpha, depth - 1);
+ score = -negamax(stats, -alpha - 1, -alpha, depth - 1);
// if fail research
if (score > alpha && score < beta)
- score = -negamax(stats, ©, -beta, -alpha, depth - 1);
+ score = -negamax(stats, -beta, -alpha, depth - 1);
}
}
- stats->ply--;
+ stats_move_unmake(stats, ©);
searched++;
if (score > alpha) {
@@ -253,12 +241,12 @@ int negamax(Stats *stats, const Board *board, int alpha, int beta, int depth) {
stats->killer_moves[0][stats->ply] = move;
}
- ttable_write(stats->ttable, board_hash(©), beta, depth,
- stats->ply, flagBeta);
+ ttable_write(stats, beta, depth, flagBeta);
return beta;
}
}
}
+
if (legal_moves == 0) {
if (isCheck) {
return -MATE_VALUE + stats->ply;
@@ -266,7 +254,7 @@ int negamax(Stats *stats, const Board *board, int alpha, int beta, int depth) {
return 0;
}
- ttable_write(stats->ttable, bhash, alpha, depth, stats->ply, flag);
+ ttable_write(stats, alpha, depth, flag);
return alpha;
}
@@ -277,14 +265,14 @@ void move_print_UCI(Move move) {
}
TTable *ttable = NULL;
-void search_position(const Board *board, int depth) {
- Stats stats = {.ttable = ttable, 0};
+void search_position(Board *board, int depth) {
+ Stats stats = {.ttable = ttable, .board = board, 0};
int alpha = -INFINITY, beta = INFINITY;
for (int crnt = 1; crnt <= depth;) {
stats.follow_pv = 1;
- int score = negamax(&stats, board, alpha, beta, crnt);
+ int score = negamax(&stats, alpha, beta, crnt);
if ((score <= alpha) || (score >= beta)) {
alpha = -INFINITY;
beta = INFINITY;
diff --git a/src/engine/stats.h b/src/engine/stats.h
@@ -0,0 +1,22 @@
+#ifndef STELLAR_STATS_H
+#define STELLAR_STATS_H
+
+#include "moves.h"
+#include "utils.h"
+
+#define MAX_PLY 64
+
+typedef struct Stats Stats;
+struct Stats {
+ Move pv_table[MAX_PLY][MAX_PLY];
+ Move killer_moves[2][MAX_PLY];
+ U32 history_moves[16][64];
+ int pv_length[MAX_PLY];
+ struct TTable *ttable;
+ Board *board;
+ int follow_pv, score_pv;
+ long nodes;
+ int ply;
+};
+
+#endif
diff --git a/src/engine/transposition.c b/src/engine/transposition.c
@@ -40,16 +40,20 @@ void ttable_clear(T *self) {
memset(self->table, 0x0, sizeof(T) + self->size * sizeof(Hashe));
}
-int ttable_read(T *self, U64 hash, int alpha, int beta, int depth, int ply) {
- assert(self);
+int ttable_read(const Stats *stats, int alpha, int beta, int depth) {
+ assert(stats);
+ assert(stats->ttable);
+
+ T *self = stats->ttable;
+ U64 hash = board_hash(stats->board);
Hashe *phashe = &self->table[hash % self->size];
if (phashe->key == hash) {
if (phashe->depth >= depth) {
int score = phashe->score;
- if (score < -MATE_SCORE) score += ply;
- if (score > MATE_SCORE) score -= ply;
+ if (score < -MATE_SCORE) score += stats->ply;
+ if (score > MATE_SCORE) score -= stats->ply;
if (phashe->flag == flagExact) return score;
if ((phashe->flag == flagAlpha) && (score <= alpha)) return alpha;
@@ -59,14 +63,17 @@ int ttable_read(T *self, U64 hash, int alpha, int beta, int depth, int ply) {
return TTABLE_UNKNOWN;
}
-void ttable_write(T *self, U64 hash, int score, int depth, int ply,
- HasheFlag flag) {
- assert(self);
+void ttable_write(const Stats *stats, int score, int depth, HasheFlag flag) {
+ assert(stats);
+ assert(stats->ttable);
+
+ T *self = stats->ttable;
+ U64 hash = board_hash(stats->board);
Hashe *phashe = &self->table[hash % self->size];
- if (score < -MATE_SCORE) score += ply;
- if (score > MATE_SCORE) score -= ply;
+ if (score < -MATE_SCORE) score += stats->ply;
+ if (score > MATE_SCORE) score -= stats->ply;
*phashe = (Hashe){
.key = hash,
diff --git a/src/engine/transposition.h b/src/engine/transposition.h
@@ -0,0 +1,28 @@
+#ifndef STELLAR_TRANSPOSITION_H
+#define STELLAR_TRANSPOSITION_H
+
+#include "stats.h"
+#include "utils.h"
+
+#define TTABLE_UNKNOWN 100000
+
+#define T TTable
+
+typedef enum HasheFlag HasheFlag;
+enum HasheFlag {
+ flagExact,
+ flagAlpha,
+ flagBeta
+};
+
+typedef struct T T;
+
+T *ttable_new(U64 size);
+void ttable_free(T **self);
+void ttable_clear(T *self);
+
+int ttable_read(const Stats *stats, int alpha, int beta, int depth);
+void ttable_write(const Stats *stats, int score, int depth, HasheFlag flag);
+
+#undef T
+#endif
diff --git a/src/include/transposition.h b/src/include/transposition.h
@@ -1,28 +0,0 @@
-#ifndef STELLAR_TRANSPOSITION_H
-#define STELLAR_TRANSPOSITION_H
-
-#include "utils.h"
-
-#define TTABLE_UNKNOWN 100000
-
-#define T TTable
-
-typedef enum HasheFlag HasheFlag;
-enum HasheFlag {
- flagExact,
- flagAlpha,
- flagBeta
-};
-
-typedef struct T T;
-
-T *ttable_new(U64 size);
-void ttable_free(T **self);
-void ttable_clear(T *self);
-
-int ttable_read(T *self, U64 hash, int alpha, int beta, int depth, int ply);
-void ttable_write(T *self, U64 hash, int score, int depth, int ply,
- HasheFlag flag);
-
-#undef T
-#endif