home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
useful
/
game
/
think
/
uchess
/
src
/
ttable.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-12
|
18KB
|
818 lines
/* ttable.c -- Transposition table code to be included in search.c */
/* #include "gnuchess.h" /* already included, see search.c */
/* #include "ttable.h" /* dito */
/* NOTE: The static evaluation cache "EETable" belongs to eval.c and cannot*/
/* be moved to ttable.c */
/* Privae types and data */
#include <proto/exec.h>
#include <exec/memory.h>
#include <proto/dos.h>
//#define TT_EXPIRATION 40000 // nominal exp node value
#ifndef AMIGA
struct hashentry
{
unsigned long hashbd;
UCHAR flags, depth; /* CHAR saves some space */
tshort score;
utshort mv;
#ifdef HASHTEST
UCHAR bd[32];
#endif /* HASHTEST */
#ifdef NEWAGE
utshort age; /* age of last use */
#endif
};
unsigned long ttblsize;
#endif // AMIGA
extern struct hashentry huge __aligned *ttable[2];
/* unsigned */ extern SHORT __aligned rehash; /* -1 is used as a flag --tpm */
#ifdef NEWAGE
utshort TTage; /* Current ttable age */
UTSHORT TTageClock, /* Count till next age tick */
TTageRate; /* new entry counts per age tick */
UTSHORT TTdepthage[MAXDEPTH+1]; /* Depth bonus for aging*/
UTSHORT newage = NEWAGE; /* Initialization tuning parameter */
extern unsigned int __aligned TTadd;
#else
unsigned int ttbllimit;
extern unsigned int TTadd;
#endif
#ifdef HASHSTATS
unsigned long ttdepthin[MAXDEPTH+1], ttdepthout[MAXDEPTH+1];
unsigned long ttrehash[MAXrehash+1];
unsigned long ttprobe[MAXDEPTH+1];
unsigned long HashCnt, HashAdd, FHashCnt, FHashAdd, HashCol, THashCol;
#endif
/* hashtable flags */
#define truescore 0x0001
#define lowerbound 0x0002
#define upperbound 0x0004
#define kingcastle 0x0008
#define queencastle 0x0010
#define evalflag 0x0020
void
Initialize_ttable ()
{
char astr[32];
int doit = true;
if (rehash < 0) rehash = MAXrehash;
while(doit && ttblsize >= (1<<13)){
ttable[0] = (struct hashentry *)malloc(sizeof(struct hashentry)*(ttblsize+rehash));
ttable[1] = (struct hashentry *)malloc(sizeof(struct hashentry)*(ttblsize+rehash));
if(ttable[0] == NULL || ttable[1] == NULL){
if(ttable[0] != NULL)free(ttable[0]);
ttblsize = ttblsize>>1;
} else doit = false;
}
if(ttable[0] == NULL || ttable[1] == NULL)
{
ShowMessage("Critical Mem Failure");
Delay(100L);
AmigaShutDown();
exit(1);
}
else {
#ifdef NEWAGE
int j;
unsigned long k;
#endif
sprintf(astr,"transposition tbl is %d\n",ttblsize);
ShowMessage(astr);
#ifdef NEWAGE
/* WARNING: Bogus parameters ahead!
* The numbers that follow are based on pure fiction
* and are not contaminated with facts
*/
TTageRate = ttblsize/3000 + 1; // try 3k, 1500 and 5000 and see
// which gives lowest node cnts
TTdepthage[0] = 32768;
for (j=1, k = 50; j<=MAXDEPTH; j++, k *= (13-j))
{
/* Maximum k = 50 * 11! ~= 2^31 (this is a fact) */
TTdepthage[j] = (TTdepthage[j-1] > k/TTageRate) ?
TTdepthage[j-1] - k/TTageRate : 0;
}
#else
ttbllimit = ttblsize<<1 - ttblsize>>2;
#endif
}
}
#define CB(i) (UCHAR) ((color[2 * (i)] ? 0x80 : 0)\
| (board[2 * (i)] << 4)\
| (color[2 * (i) + 1] ? 0x8 : 0)\
| (board[2 * (i) + 1]))
int __inline
ProbeTTable (int side,
int depth,
int ply,
SHORT *alpha,
SHORT *beta,
SHORT *score)
/*
* Look for the current board position in the transposition table.
*/
{
register struct hashentry *ptbl;
register /*unsigned*/ SHORT i = 0; /*to match new type of rehash --tpm*/
#ifndef NEWAGE
ptbl = &ttable[side][hashkey % ttblsize];
while (true)
{
if (ptbl->depth == 0) return false;
if (ptbl->hashbd == hashbd) break;
if (++i > rehash) return false;
ptbl++;
}
#else
for (i=rehash, ptbl = &ttable[side][hashkey % ttblsize];
ptbl->hashbd != hashbd; ptbl++)
if (--i == 0) return false;
/* Update age of rediscovered node */
ptbl->age = TTage - TTdepthage[ptbl->depth];
#endif
PV = SwagHt = ptbl->mv;
if ((ptbl->depth >= (short) depth))
{
if (ptbl->flags & truescore)
{
*score = ptbl->score;
/* adjust *score so moves to mate is from root */
if (*score > 9000) *score -= ply;
else if (*score < -9000) *score += ply;
*beta = -20000;
}
else if (ptbl->flags & lowerbound)
{
if (ptbl->score > *alpha)
*alpha = ptbl->score;
}
return (true);
}
return (false);
}
int __inline
PutInTTable
(int side,
int score,
int depth,
int ply,
//int alpha,
int beta,
unsigned int mv)
/*
* Store the current board position in the transposition table.
*/
{
register struct hashentry *ptbl,*oldest;
unsigned short old;
register /*unsigned*/ SHORT i = 0; /*to match new type of rehash --tpm*/
#ifdef NEWAGE
i=rehash;
old = 0;
ptbl = &ttable[side][hashkey % ttblsize];
while (true)
{
if (ptbl->hashbd == hashbd)
{
if(ptbl->depth > (UCHAR)depth) return false;
else break;
}
if (((TTage - ptbl->age) /*& 0xFFFF*/) > old)
{
old = (TTage - ptbl->age)/* & 0xFFFF*/;
//if (old > TT_EXPIRATION) break; /* Use this expired entry */
oldest = ptbl;
}
if (--i == 0)
{
ptbl = oldest;
break;
}
ptbl++;
}
if (--TTageClock == 0)
{
TTageClock = TTageRate;
TTage++; /* Everyone is now just a little older */
}
TTadd++;
/* Update age of this node */
ptbl->age = TTage - TTdepthage[ptbl->depth];
#else
TTadd++;
#endif
#ifdef HASHSTATS
HashAdd++;
#endif
if(ptbl->depth > (UCHAR)depth) return false;
ptbl->hashbd = hashbd;
ptbl->depth = (UCHAR) depth;
ptbl->score = score;
ptbl->mv = mv;
if (score > beta)
{
ptbl->flags = lowerbound;
ptbl->score = beta + 1;
}
else
{
/* adjust score so moves to mate is from this ply */
if (score > 9000) score += ply;
else if (score < -9000 && score != -9999) score -= ply;
ptbl->score = score;
ptbl->flags = truescore;
}
return true;
}
void
ZeroTTable (int iop) /* iop: 0= clear any, 1= clear agged */
{
#ifdef NEWAGE
if(iop==0)
{
TTageClock = TTageRate;
TTage = TTdepthage[0]+1; /* used to be newage + 1Zero entries are pre-expired. */
//TTage = TT_EXPIRATION + 1;
//TTageRate = ttblsize/(newage/2); /* Average 1/2 of table will be expired */
/* zero the age of all ttable entries */
if (!TTadd)
return;
#ifdef AMIGA
ClearMem(ttable[0],sizeof(struct hashentry)*(ttblsize+rehash));
ClearMem(ttable[1],sizeof(struct hashentry)*(ttblsize+rehash));
#else
memset(ttable[white],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
memset(ttable[black],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
#endif
TTadd = 0;
}
#ifdef ZERO_1_DOES
else
{
/* Just add a major increment to TTage */
TTage += (TTdepthage[0] - TTdepthage[MAXDEPTH-1]); /* Just a guess */
}
#endif
#else /* not NEWAGE */
if ((iop==0 && TTadd) || TTadd > ttbllimit)
{
#ifdef AMIGA
ClearMem(ttable[0],sizeof(struct hashentry)*(ttblsize+rehash));
ClearMem(ttable[1],sizeof(struct hashentry)*(ttblsize+rehash));
#else
memset(ttable[white],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
memset(ttable[black],0,sizeof(struct hashentry)*(unsigned)(ttblsize+rehash));
#endif
TTadd = 0;
}
#endif /* NEWAGE */
}
/************************* Hash table statistics ****************************/
#ifdef HASHSTATS
long EADD,EGET; /* Eval cache stats */
void
ClearHashStats() /* initialize the stats */
{
memset ((CHAR *) ttdepthin, 0, sizeof (ttdepthin));
memset ((CHAR *) ttdepthout, 0, sizeof (ttdepthout));
memset ((CHAR *) ttrehash, 0, sizeof (ttrehash));
memset ((CHAR *) ttprobe, 0, sizeof (ttprobe));
HashAdd = HashCnt = THashCol = HashCol = FHashCnt = FHashAdd = 0;
EADD = EGET = 0;
}
void
ShowHashStats() /* print the stats */
{
int ii;
printf("Probe: ");
for(ii=0;ii<MAXDEPTH;ii++)
if (ttprobe[ii])
printf(" %d:%ld", ii, ttprobe[ii]);
printf("\nIn/Out: ");
for(ii=0;ii<MAXDEPTH;ii++)
if (ttdepthin[ii] || ttdepthout[ii])