#ifndef TTABLE_H
#define TTABLE_H

// includes

#include "moveseq.h"

// macros

#define HASHSLOTS 2048 


#define TTABLE_QUIESCENT   1
#define TTABLE_LOWERBOUND  2
#define TTABLE_UPPERBOUND  4
#define TTABLE_EXACTSCORE  8
#define TTABLE_UNDERTHREAT  16
#define TTABLE_FLAGMASK (TTABLE_QUIESCENT| TTABLE_LOWERBOUND|TTABLE_UPPERBOUND|TTABLE_EXACTSCORE|TTABLE_UNDERTHREAT)



// types

typedef struct{
   HashType key;    /* Full 64 bit hash */
   int move;        /* Best move */
   int16_t score;       /* Estimated score, may be lower or upper bound */
   uint16_t age;      
   uint8_t flag;    /* Is this alpha, beta, quiescent or exact? */
   uint8_t depth;   /* Search depth */
} ttable_slot_t;   

typedef struct{
    unsigned long TotalGetHashCnt;
    unsigned long GoodGetHashCnt;
    unsigned long TotalPutHashCnt;
    unsigned long CollHashCnt;
    unsigned int Size;
    unsigned long Mask;
    ttable_slot_t *Slot;
    uint16_t Age;
}ttable_t;

// variables

extern ttable_t TTable[1];

// functions

void TTablePut(ttable_t *ttable,
	       board_t *board, 
	       uint8_t depth, 
	       uint8_t ply, 
	       int alpha, 
	       int beta, 
	       int under_threat,
	       int score, 
	       int move);

int TTableGet(ttable_t *ttable,
		  board_t *board, 
		  uint8_t ply, 
		  uint8_t *depth,
		  uint8_t *flag,
		  int *score, 
		  int *move);

void TTableGetPV(ttable_t *ttable,
		 board_t *board, 
		 int score,
		 int maxcnt,
		 moveseq_t *moveseq
		 );

void TTShow(ttable_t *ttable, board_t *board);

void TTableInit(ttable_t *ttable);
void TTableClear(ttable_t *ttable);
void TTableZero(ttable_t *ttable);
void TTableResetStats(ttable_t *ttable);
void TTableSetSize(ttable_t *ttable, unsigned int size);
void TTableSetSizeMb(ttable_t *ttable, unsigned int size);
void TTableIncAge(ttable_t *ttable);
void TTableRefresh(ttable_t *ttable, board_t *board);
void TTableStatsShow(ttable_t *ttable);

#endif
