#ifdef WIN32
# include <windows.h>
-# define CPUtime 1000.*clock
+# define CPUtime (1000./CLOCKS_PER_SEC)*clock
int Input()
{ // checks for waiting input in pipe
static int init; static HANDLE inp; DWORD cnt;
gettimeofday(&t, NULL);
return t.tv_sec*1000 + t.tv_usec/1000;
}
+ double CPUtime()
+ { // get CPU time used by process, converted to 'MILLICLOCKS'
+ struct tms cpuTimes;
+ static int cps = 0; static double ms_per_clk;
+ if(!cps) cps = sysconf(_SC_CLK_TCK), ms_per_clk = 1000./cps;
+ times(&cpuTimes);
+ return (cpuTimes.tms_utime + cpuTimes.tms_stime) * ms_per_clk;
+ }
int Input()
{
int cnt;
typedef long long int Key;
int ply, nodeCount, forceMove, choice, rootMove, lastGameMove, rootScore, abortFlag, postThinking=1; // some frequently used data
-int maxDepth=MAXPLY-2, timeControl=3000, mps=40, inc, timePerMove, timeLeft=1000; // TC parameters
-int rootFirst, rootCurrent, rootLast, rootPly, margin;
+int maxDepth=MAXPLY-2, timeControl=3000, mps=40, inc, timePerMove, timeLeft=1000, nodeRate=-1; // TC parameters
+int rootFirst, rootCurrent, rootLast, rootPly, rootScore, margin;
#define H_LOWER 1
#define H_UPPER 2
-int ReadClock (int start);
+int ReadClock (int start, int print);
char *MoveToText (int move);
int TimeIsUp (int mode);
tail = pvPtr; pvPtr = pvStart; *pvPtr++ = moveStack[curMove]; // alpha < score < beta: move starts new PV
while(*pvPtr++ = *tail++); // copy PV of daughter node behind it (including 0 sentinel)
if(ply == 0) { // in root we print this PV
- int xbScore = (score > INF-100 ? 100000 + INF - score : score < 100-INF ? -100000 - score - INF : score);
- printf("%d %d %d %d", iterDepth, xbScore, ReadClock(0)/10, nodeCount);
+ rootScore = (score > INF-100 ? 100000 + INF - score : score < 100-INF ? -100000 - score - INF : score);
+ printf("%d %d %d %d", iterDepth, rootScore, ReadClock(0, 1)/10, nodeCount);
for(tail=pvStart; *tail; tail++) printf(" %s", MoveToText(*tail));
printf("\n"); fflush(stdout);
ff->move = moveStack[bestNr];
int t, targetTime, panicTime;
if(Input() && DoCommand(1)) return 1; // abort if command waiting that cannot be handled during search
if(engineSide == ANALYZE) return 0; // no timing on analyze or ponder
- t = ReadClock(0);
+ t = ReadClock(0, 0);
if(timePerMove >= 0) { // fixed time per move
targetTime = panicTime = 10*timeLeft - 30;
} else if(mps) { // classical TC
int contemptFactor; // likewise
int
-ReadClock (int start)
+ReadClock (int start, int print)
{
- static int startTime;
- int t = GetTickCount();
- if(start) startTime = t;
+ static int startTime; int t;
+ if(nodeRate > 0 && !start && !print) return nodeCount*1000LL/nodeRate;
+ t = (nodeRate >= 0 ? (int)(CPUtime()) : GetTickCount());
+ if(start) startTime = t, nodeCount = 0;
return t - startTime; // msec
}
if(!strcmp(command, "nopost")) { postThinking = OFF;return 0; }
if(!strcmp(command, "random")) { randomize = ON; return 0; }
if(!strcmp(command, ".")) { // periodic update request;
- printf("stat01: %d %d %d %d %d %s\n", ReadClock(0)/10, nodeCount, rootPly,
+ printf("stat01: %d %d %d %d %d %s\n", ReadClock(0, 1)/10, nodeCount, rootPly,
rootLast - rootCurrent + 1, rootLast - rootFirst, MoveToText(moveStack[rootCurrent]));
fflush(stdout); return 0;
}
return 1;
}
if(!strcmp(command, "protover")){
- printf("feature ping=1 setboard=1 colors=0 usermove=1 memory=1 debug=1 reuse=0 sigint=0 sigterm=0 exclude=1 myname=\"CrazyWa " VERSION "\"\n");
+ printf("feature ping=1 setboard=1 colors=0 usermove=1 memory=1 debug=1 reuse=0 sigint=0 sigterm=0 "
+ "exclude=1 nps=1 myname=\"CrazyWa " VERSION "\"\n");
printf("feature variants=\"crazyhouse,shogi,minishogi,judkinshogi,torishogi,euroshogi,crazywa,kyotoshogi,"
"5x5+4_shogi,5x5+5_shogi,6x6+6_shogi,7x7+6_shogi,11x17+16_chu\"\n");
printf("feature option=\"Resign -check 0\"\n"); // example of an engine-defined option
}
if(!strcmp(command, "sd")) { sscanf(inBuf+2, "%d", &maxDepth); return 1; }
if(!strcmp(command, "st")) { sscanf(inBuf+2, "%d", &timePerMove); return 1; }
+ if(!strcmp(command, "nps")) { sscanf(inBuf+4, "%d", &nodeRate); return 1; }
if(!strcmp(command, "memory")) { if(SetMemorySize(atoi(inBuf+7))) printf("tellusererror Not enough memory\n"), exit(-1); return 1; }
if(!strcmp(command, "ping")) { printf("pong%s", inBuf+4); return 1; }
// if(!strcmp(command, "")) { sscanf(inBuf, " %d", &); return 1; }
- if(!strcmp(command, "new")) { engineSide = BLACK; stm = WHITE; maxDepth = MAXPLY-2; randomize = OFF;
+ if(!strcmp(command, "new")) { engineSide = BLACK; stm = WHITE; maxDepth = MAXPLY-2; randomize = OFF; nodeRate = -1;
moveNr = 0; ranKey = GetTickCount() | 0x1001; MapClear(0); return 1; }
if(!strcmp(command, "variant")) { GameInit(inBuf + 8); Setup(startPos); return 1; }
if(!strcmp(command, "setboard")){ engineSide = NONE; stm = Setup(inBuf+9); MapClear(0); return 1; }
if(stm == engineSide) { // if it is the engine's turn to move, set it thinking, and let it move
{int i;for(i=0; i<=hashMask+3; i++) /*if(hashTable[i].score != hashTable[i].lim)*/ hashTable[i].lock = 0;}
- nodeCount = forceMove = undoInfo.move = abortFlag = 0; ReadClock(1);
+ forceMove = undoInfo.move = abortFlag = 0; ReadClock(1, 0);
for(i=0;i<1<<16;i++) history[i] = 0; //>>= 1;
for(i=0;i<1<<17;i++) mateKillers[i] = 0;
score = Search(stm^COLOR, -INF, INF, &undoInfo, maxDepth, 0, maxDepth);
+ if(nodeRate >= 0) printf("%d %d %d %d <done>\n", rootPly, rootScore, ReadClock(0, 1)/10, nodeCount); // make sure total time is printed
if(!undoInfo.move) { // no move, game apparently ended
engineSide = NONE; // so stop playing
// now it is not our turn (anymore)
if(engineSide == ANALYZE) { // in analysis, we always ponder the position
- nodeCount = forceMove = undoInfo.move = abortFlag = 0; ReadClock(1);
+ forceMove = undoInfo.move = abortFlag = 0; ReadClock(1, 0);
Search(stm^COLOR, -INF, INF, &undoInfo, maxDepth, 0, maxDepth);
}
#if 0