stellar

Stellar - Chess engine written in C
Log | Files | Refs

transposition.c (1983B)


      1 #include <cul/assert.h>
      2 #include <cul/mem.h>
      3 #include <string.h>
      4 
      5 #include "board.h"
      6 #include "moves.h"
      7 #include "transposition.h"
      8 
      9 #define TTABLE_SIZE 0x400000
     10 
     11 #define T TTable
     12 
     13 typedef struct Hashe Hashe;
     14 struct Hashe {
     15     U64 key;
     16     Move best;
     17     int depth;
     18     int score;
     19     HasheFlag flag;
     20 };
     21 
     22 struct T {
     23     U64 size;
     24     Hashe table[];
     25 };
     26 
     27 T *ttable_new(U64 size) {
     28     T *self = CALLOC(1, sizeof(T) + size * sizeof(Hashe));
     29     self->size = size;
     30     return self;
     31 }
     32 
     33 void ttable_free(T **self) {
     34     assert(self && *self);
     35     FREE(*self);
     36 }
     37 
     38 void ttable_clear(T *self) {
     39     assert(self);
     40     memset(self->table, 0x0, sizeof(T) + self->size * sizeof(Hashe));
     41 }
     42 
     43 int ttable_read(const Stats *stats, Move *best, int alpha, int beta,
     44                 int depth) {
     45     assert(stats);
     46     assert(stats->ttable);
     47 
     48     T *self = stats->ttable;
     49     U64 hash = board_hash(stats->board);
     50 
     51     Hashe *phashe = &self->table[hash % self->size];
     52     if (phashe->key == hash) {
     53         if (phashe->depth >= depth) {
     54             int score = phashe->score;
     55 
     56             if (score < -MATE_SCORE) score += stats->ply;
     57             if (score > MATE_SCORE) score -= stats->ply;
     58 
     59             if (phashe->flag == flagExact) return score;
     60             if ((phashe->flag == flagAlpha) && (score <= alpha)) return alpha;
     61             if ((phashe->flag == flagBeta) && (score >= beta)) return beta;
     62         }
     63         *best = phashe->best;
     64     }
     65     return TTABLE_UNKNOWN;
     66 }
     67 
     68 void ttable_write(const Stats *stats, Move best, int score, int depth,
     69                   HasheFlag flag) {
     70     assert(stats);
     71     assert(stats->ttable);
     72 
     73     T *self = stats->ttable;
     74     U64 hash = board_hash(stats->board);
     75 
     76     Hashe *phashe = &self->table[hash % self->size];
     77 
     78     if (score < -MATE_SCORE) score += stats->ply;
     79     if (score > MATE_SCORE) score -= stats->ply;
     80 
     81     *phashe = (Hashe){
     82         .key = hash,
     83         .best = best,
     84         .depth = depth,
     85         .score = score,
     86         .flag = flag,
     87     };
     88 }