char fireMask;\r
} UndoInfo;\r
\r
-char *array;\r
+char *array, *reason;\r
int bWidth, bHeight, bsize, zone, currentVariant;\r
int stm, xstm, hashKeyH, hashKeyL, framePtr, msp, nonCapts, rootEval, retMSP, retFirst, retDep, pvPtr, level, cnt50, chuFlag=1, tenFlag, mobilityScore;\r
-int nodes, startTime, tlim1, tlim2;\r
-Move retMove, moveStack[10000], path[100], repStack[300], pv[1000];\r
+int nodes, startTime, tlim1, tlim2, repCnt, comp;\r
+Move retMove, moveStack[10000], path[100], repStack[300], pv[1000], repeatMove[300];\r
\r
#define X 36 /* slider */\r
#define R 37 /* jump capture */\r
\r
// piece-square tables\r
for(i=0; i<BH; i++) for(j=0; j<BH; j++) {\r
- int s = BW*i + j, d = BH*(BH-2) - (2*i - BH + 1)*(2*i - BH + 1) - (2*j - BH + 1)*(2*j - BH + 1);\r
+ int s = BW*i + j, d = BH*(BH-2) - abs(2*i - BH + 1)*(BH-1) - (2*j - BH + 1)*(2*j - BH + 1);\r
+ PST[s] = 0;\r
PST[BH+s] = d/4 - (i == 0 || i == BH-1 ? 15 : 0) - (j == 0 || j == BH-1 ? 15 : 0);\r
PST[BH*BW+s] = d/6;\r
PST[BH*BW+BH+s] = d/12;\r
GenCapts(int sqr, int victimValue)\r
{ // generate all moves that capture the piece on the given square\r
int i, range, att = attacks[2*sqr + stm];\r
-//printf("GenCapts(%d,%d)\n",sqr,victimValue);\r
+//printf("GenCapts(%c%d,%d) %08x\n",sqr%BW+'a',sqr/BW,victimValue,att);\r
if(!att) return; // no attackers at all!\r
for(i=0; i<8; i++) { // try all rays\r
int x, v, jumper, jcapt=0;\r
for(i=0; i<8; i++) { // scan all knight jumps to locate source\r
int x = sqr - nStep[i], attacker = board[x];\r
if(attacker == EMPTY || (attacker & TYPE) != stm) continue;\r
- if(p[attacker].range[i] <= N && p[attacker].range[i] >= S) { // has Knight jump in our direction\r
+ if(p[attacker].range[i] <= L && p[attacker].range[i] >= S || p[attacker].range[i] == N) { // has Knight jump in our direction\r
NewCapture(x, sqr + victimValue, p[attacker].promoFlag); // plain jump (as in N)\r
if(p[attacker].range[i] < N) { // Lion power; generate double captures over two possible intermediates\r
int v = kStep[i]; // leftish path\r
if(flag & depth >= 0) printf("%2d:%d made %d/%d %s\n", depth, iterDep, curMove, msp, MoveToText(moveStack[curMove], 0));\r
for(i=2; i<=cnt50; i+=2) if(repStack[level-i+200] == hashKeyH) {\r
moveStack[curMove] = 0; // erase forbidden move\r
- score = -INF; goto repetition;\r
+ if(!level) repeatMove[repCnt++] = move & 0xFFFFFF; // remember outlawed move\r
+ score = -INF; moveStack[curMove] = 0; goto repetition;\r
}\r
repStack[level+200] = hashKeyH;\r
\r
if(*moveText == '+') ret |= PROMOTE;\r
printf("# suppress = %c%d\n", sup1%BW+'a', sup1/BW);\r
MapFromScratch(attacks);\r
- postThinking--;\r
+ postThinking--; repCnt = 0;\r
Search(-INF-1, INF+1, 0, 1, sup1 & ~PROMOTE, sup2);\r
postThinking++;\r
for(i=retFirst; i<retMSP; i++) {\r
if(!(flags & promoBoard[f])) moveStack[i] |= DEFER; // came from outside zone, so essential deferral\r
}\r
}\r
- if(i >= retMSP)\r
- for(i=retFirst; i<retMSP; i++) printf("# %d. %08x %08x %s\n", i-20, moveStack[i], ret, MoveToText(moveStack[i], 0));\r
+ if(i >= retMSP) {\r
+ for(i=retFirst; i<retMSP; i++) printf("# %d. %08x %08x %s\n", i-50, moveStack[i], ret, MoveToText(moveStack[i], 0));\r
+ reason = NULL;\r
+ for(i=0; i<repCnt; i++) {if((repeatMove[i] & 0xFFFFFF) == ret) {\r
+ reason = "Repeats earlier position";\r
+ break;\r
+ }\r
+ printf("# %d. %08x %08x %s\n", i, repeatMove[i], ret, MoveToText(repeatMove[i], 0));\r
+}\r
+ }\r
}\r
return (i >= retMSP ? INVALID : moveStack[i]);\r
}\r
//pmap(attacks, WHITE);\r
//pmap(attacks, BLACK);\r
//flag=1;\r
- postThinking--;\r
+ postThinking--; repCnt = 0;\r
Search(-INF-1, INF+1, 0, 1, sup1 & ~PROMOTE, sup2);\r
postThinking++;\r
flag=0;\r
tlim2 = 1.9*targetTime;\r
nodes = 0;\r
MapFromScratch(attacks);\r
+ retMove = INVALID; repCnt = 0;\r
score = Search(-INF-1, INF+1, rootEval, 20, sup1, sup2);\r
*move = retMove;\r
*ponderMove = INVALID;\r
\r
void PrintResult(int stm, int score)\r
{\r
- if(score == 0) printf("1/2-1/2\n");\r
- if(score > 0 && stm == WHITE || score < 0 && stm == BLACK) printf("1-0\n");\r
- else printf("0-1\n");\r
+ char tail[100];\r
+ if(reason) sprintf(tail, " {%s}", reason); else *tail = 0;\r
+ if(score == 0) printf("1/2-1/2%s\n", tail);\r
+ if(score > 0 && stm == WHITE || score < 0 && stm == BLACK) printf("1-0%s\n", tail);\r
+ else printf("0-1%s\n", tail);\r
}\r
\r
main()\r
score = SearchBestMove(stm, timeLeft, mps, timeControl, inc, timePerMove, &move, &ponderMove);\r
\r
if(move == INVALID) { // game apparently ended\r
+ int kcapt = 0, xstm = stm ^ WHITE, king, k = p[king=royal[xstm]].pos;\r
+ if( k != ABSENT) { // test if King capture possible\r
+ if(attacks[2*k + stm]) {\r
+ if( p[king + 2].pos == ABSENT ) kcapt = 1; // we have an attack on his only King\r
+ }\r
+ } else { // he has no king! Test for attacks on Crown Prince\r
+ k = p[king + 2].pos;\r
+ if(attacks[2*k + stm]) kcapt = 1; // we have attack on Crown Prince\r
+ }\r
+ if(kcapt) { // print King capture before claiming\r
+ GenCapts(k, 0);\r
+ printf("move %s\n", MoveToText(moveStack[msp-1], 1));\r
+ reason = "king capture";\r
+ } else reason = "resign";\r
engineSide = NONE; // so stop playing\r
PrintResult(stm, score);\r
} else {\r
if(!strcmp(command, "memory")) { SetMemorySize(atoi(inBuf+7)); continue; }\r
if(!strcmp(command, "ping")) { printf("pong%s", inBuf+4); continue; }\r
// if(!strcmp(command, "")) { sscanf(inBuf, " %d", &); continue; }\r
- if(!strcmp(command, "new")) { engineSide = BLACK; Init(V_CHESS); stm = Setup2(DEFAULT_FEN); maxDepth = MAXPLY; randomize = OFF; continue; }\r
+ if(!strcmp(command, "new")) {\r
+ engineSide = BLACK; Init(V_CHESS); stm = Setup2(DEFAULT_FEN); maxDepth = MAXPLY; randomize = OFF; comp = 0;\r
+ continue;\r
+ }\r
if(!strcmp(command, "setboard")){ engineSide = NONE; stm = Setup2(inBuf+9); continue; }\r
if(!strcmp(command, "easy")) { ponder = OFF; continue; }\r
if(!strcmp(command, "hard")) { ponder = ON; continue; }\r
if(!strcmp(command, "l")) { pplist(); continue; }\r
// ignored commands:\r
if(!strcmp(command, "xboard")) { continue; }\r
- if(!strcmp(command, "computer")){ continue; }\r
+ if(!strcmp(command, "computer")){ comp = 1; continue; }\r
if(!strcmp(command, "name")) { continue; }\r
if(!strcmp(command, "ics")) { continue; }\r
if(!strcmp(command, "accepted")){ continue; }\r
if(!strcmp(command, "")) { continue; }\r
if(!strcmp(command, "usermove")){\r
int move = ParseMove(inBuf+9);\r
- if(move == INVALID) printf("Illegal move\n");\r
- else {\r
+ if(move == INVALID) {\r
+ if(reason) printf("Illegal move {%s}\n", reason); else printf("%s\n", reason="Illegal move");\r
+ if(comp) PrintResult(stm, -INF); // against computer: claim\r
+ } else {\r
stm = MakeMove2(stm, move);\r
ponderMove = INVALID;\r
gameMove[moveNr++] = move; // remember game\r