#ifndef HASH_H_INCLUDED
#define HASH_H_INCLUDED

#include <stdint.h>
#include "ramjet.h"
#include "move.h"
#include "eval.h"

// compressed move, eval and depth types
typedef uint16_t HASHMOVE;
typedef int16_t HASHEVAL;
typedef uint8_t HASHDEPTH;

// the hash flag type
typedef uint8_t HASHFLAG;
#define HF_NULL 0
#define HF_BETA 1
#define HF_ALPHA 2
#define HF_EXACT 3

// the hash entry data type
typedef struct {
    HASHKEY key;
    HASHMOVE mv;
    HASHEVAL scr;
    HASHDEPTH depth;
    HASHFLAG flag;
} HASHENTRY;

// the hash table data type
typedef struct {
    HASHENTRY* entry;
    int n;
} HASHTABLE;

// hash memory release
void hash_free(HASHTABLE* ht);

// hash memory allocation
int hash_alloc_n(HASHTABLE* ht, int dim);
int hash_alloc_mb(HASHTABLE* ht, int mb);

// initialise the hash table
void hash_init(HASHTABLE* ht);

// set all entries to invalid
void hash_clear(HASHTABLE* ht);

// insert a new entry
void hash_insert(HASHTABLE* ht, HASHKEY key, MOVE mv, EVAL scr, int ply, int depth, HASHFLAG flag);

// the hash probe return values
typedef enum {HP_NONE, HP_MOVE, HP_PRUNE} HASHPROBE;

// probe the hash table
HASHPROBE hash_probe(HASHTABLE* ht, HASHKEY key, MOVE* mv, EVAL* scr, int ply, int depth, EVAL alpha, EVAL beta);

// test the functions above
int hash_test();

#endif // HASH_H_INCLUDED
