#include "sjeng.h"
#include "protos.h"
#include "extvars.h"
#undef USE_EGTB
#define XX 127
#define KINGCAP 50000
typedef unsigned int INDEX;
typedef int square;
#if defined (_MSC_VER)
#define TB_FASTCALL __fastcall
#else
#define TB_FASTCALL
#endif
typedef int color;
#define x_colorWhite 0
#define x_colorBlack 1
#define x_colorNeutral 2
#define COLOR_DECLARED
typedef int piece;
#define x_pieceNone 0
#define x_piecePawn 1
#define x_pieceKnight 2
#define x_pieceBishop 3
#define x_pieceRook 4
#define x_pieceQueen 5
#define x_pieceKing 6
#define PIECES_DECLARED
typedef signed char tb_t;
#define pageL 65536
#define tbbe_ssL ((pageL-4)/2)
#define bev_broken (tbbe_ssL+1)
#define bev_mi1 tbbe_ssL
#define bev_mimin 1
#define bev_draw 0
#define bev_limax (-1)
#define bev_li0 (-tbbe_ssL)
typedef INDEX (TB_FASTCALL * PfnCalcIndex)
(square*, square*, square, int fInverse);
extern int IDescFindFromCounters (int*);
extern int FRegisteredFun (int, color);
extern PfnCalcIndex PfnIndCalcFun (int, color);
extern int TB_FASTCALL L_TbtProbeTable (int, color, INDEX);
extern int IInitializeTb (char*);
extern int FTbSetCacheSize(void *pv, unsigned long cbSize);
#define PfnIndCalc PfnIndCalcFun
#define FRegistered FRegisteredFun
int EGTBProbes;
int EGTBHits;
int EGTBPieces;
int EGTBCacheSize;
char EGTBDir[STR_BUFF];
void init_egtb(void)
{
#ifdef USE_EGTB
void *buffer;
buffer = malloc(EGTBCacheSize);
if (buffer == NULL && (EGTBCacheSize != 0))
{
printf("Could not allocate EGTB buffer.\n");
exit(EXIT_FAILURE);
};
EGTBPieces = IInitializeTb (EGTBDir);
printf("%d piece endgame tablebases found\n", EGTBPieces);
printf("Allocated %dKb for indices and tables.\n",((cbEGTBCompBytes+1023)/1024));
if(FTbSetCacheSize (buffer, EGTBCacheSize) == FALSE
&& (EGTBCacheSize != 0))
{
printf("Could not enable EGTB buffer.\n");
exit(EXIT_FAILURE);
};
return;
#else
return;
#endif
}
const static int EGTranslate(int sqidx)
{
int r;
r = (((rank(sqidx)-1)*8)+(file(sqidx)-1));
return r;
}
int probe_egtb(void)
{
#ifdef USE_EGTB
int *psqW, *psqB;
int rgiCounters[10] = {0,0,0,0,0,0,0,0,0,0};
int side;
int fInvert;
int sqEnP;
int wi = 1, W[8] = {6,0,0,0,0,0};
int bi = 1, B[8] = {6,0,0,0,0,0};
int tbScore;
INDEX ind;
int j, a, i;
int iTb;
EGTBProbes++;
W[4] = EGTranslate(wking_loc);
B[4] = EGTranslate(bking_loc);
for (j = 1, a = 1;(a <= piece_count); j++)
{
i = pieces[j];
if (!i)
continue;
else
a++;
switch(board[i])
{
case wpawn:
rgiCounters[0]++;
W[wi] = 1;
W[wi+4] = EGTranslate(i);
wi++;
break;
case wknight:
rgiCounters[1]++;
W[wi] = 2;
W[wi+4] = EGTranslate(i);
wi++;
break;
case wbishop:
rgiCounters[2]++;
W[wi] = 3;
W[wi+4] = EGTranslate(i);
wi++;
break;
case wrook:
rgiCounters[3]++;
W[wi] = 4;
W[wi+4] = EGTranslate(i);
wi++;
break;
case wqueen:
rgiCounters[4]++;
W[wi] = 5;
W[wi+4] = EGTranslate(i);
wi++;
break;
case bpawn:
rgiCounters[5]++;
B[bi] = 1;
B[bi+4] = EGTranslate(i);
bi++;
break;
case bknight:
rgiCounters[6]++;
B[bi] = 2;
B[bi+4] = EGTranslate(i);
bi++;
break;
case bbishop:
rgiCounters[7]++;
B[bi] = 3;
B[bi+4] = EGTranslate(i);
bi++;
break;
case brook:
rgiCounters[8]++;
B[bi] = 4;
B[bi+4] = EGTranslate(i);
bi++;
break;
case bqueen:
rgiCounters[9]++;
B[bi] = 5;
B[bi+4] = EGTranslate(i);
bi++;
break;
}
}
if (wi >= 4 || bi >= 4)
{
return KINGCAP;
}
iTb = IDescFindFromCounters (rgiCounters);
if (0 == iTb)
{
return KINGCAP;
}
else if (iTb > 0)
{
side = !white_to_move;
fInvert = 0;
psqW = W;
psqB = B;
}
else
{
side = white_to_move;
fInvert = 1;
psqW = B;
psqB = W;
iTb = -iTb;
}
if (!FRegistered(iTb, side))
return KINGCAP;
if (ep_square == 0)
{
sqEnP = XX;
}
else
{
if (white_to_move)
{
if (board[ep_square - 11] == wpawn || board[ep_square - 13] == wpawn)
sqEnP = EGTranslate(ep_square);
else
sqEnP = XX;
}
else
{
if (board[ep_square + 11] == bpawn || board[ep_square + 13] == bpawn)
sqEnP = EGTranslate(ep_square);
else
sqEnP = XX;
}
}
ind = PfnIndCalc(iTb, side) (psqW, psqB, sqEnP, fInvert);
tbScore = L_TbtProbeTable( iTb, side, ind);
if (tbScore == bev_broken) return KINGCAP;
EGTBHits++;
if (tbScore > 0)
{
return ((tbScore-bev_mi1)*2+INF-ply-1);
}
else if (tbScore < 0)
{
return ((tbScore+bev_mi1)*2-INF+ply);
}
return 0;
#else
return KINGCAP;
#endif
}