Detect stalemate
[hachu.git] / hachu.c
diff --git a/hachu.c b/hachu.c
index 3367f3c..564ad9a 100644 (file)
--- a/hachu.c
+++ b/hachu.c
@@ -140,7 +140,7 @@ typedef struct {
 } UndoInfo;\r
 \r
 char *array, fenArray[4000], startPos[4000], *reason, checkStack[300];\r
-int bWidth, bHeight, bsize, zone, currentVariant, chuFlag, tenFlag, chessFlag, repDraws, tsume, pvCuts, allowRep, entryProm;\r
+int bWidth, bHeight, bsize, zone, currentVariant, chuFlag, tenFlag, chessFlag, repDraws, stalemate, tsume, pvCuts, allowRep, entryProm;\r
 int stm, xstm, hashKeyH=1, hashKeyL=1, framePtr, msp, nonCapts, rootEval, filling, promoDelta;\r
 int retMSP, retFirst, retDep, pvPtr, level, cnt50, mobilityScore;\r
 int ll, lr, ul, ur; // corner squares\r
@@ -898,7 +898,8 @@ Init (int var)
   chuFlag = (currentVariant == V_CHU || currentVariant == V_LION);\r
   tenFlag = (currentVariant == V_TENJIKU);\r
   chessFlag = (currentVariant == V_CHESS || currentVariant == V_LION);\r
-  repDraws  = (currentVariant == V_CHESS || currentVariant == V_SHATRANJ || currentVariant == V_MAKRUK || currentVariant == V_LION);\r
+  stalemate = (currentVariant == V_CHESS || currentVariant == V_MAKRUK || currentVariant == V_LION);\r
+  repDraws  = (stalemate || currentVariant == V_SHATRANJ);\r
   ll = 0; lr = bHeight - 1; ul = (bHeight - 1)*bWidth; ur = ul + bHeight - 1;\r
 \r
   for(i= -1; i<9; i++) { // board steps in linear coordinates\r
@@ -1841,6 +1842,12 @@ if(PATH) printf("%d:%2d:%2d msp=%d\n",level,depth,iterDep,msp);
 if(PATH) printf("captures on %d generated, msp=%d, group=%d, threshold=%d\n", nextVictim, msp, group, threshold);\r
              goto extractMove; // in auto-fail phase, only search if they might auto-fail-hi\r
            }\r
+if(PATH) printf("# autofail=%d\n", autoFail);\r
+           if(autoFail) { // non-captures cannot auto-fail; flush queued captures first\r
+if(PATH) printf("# autofail end (%d-%d)\n", firstMove, msp);\r
+             autoFail = 0; curMove = firstMove - 1; continue; // release stashed moves for search\r
+           }\r
+           phase = 4; // out of victims: all captures generated\r
            if(chessFlag && promoSuppress != ABSENT) { // e.p. rights. Create e.p. captures as Lion moves\r
                int n = board[promoSuppress-1], old = msp; // a-side neighbor of pushed pawn\r
                if( n != EMPTY && (n&TYPE) == stm && p[n].value == 80 ) NewCapture(promoSuppress-1, SPECIAL + 20 - 4*stm, 0);\r
@@ -1848,12 +1855,6 @@ if(PATH) printf("captures on %d generated, msp=%d, group=%d, threshold=%d\n", ne
                if( n != EMPTY && (n&TYPE) == stm && p[n].value == 80 ) NewCapture(promoSuppress+1, SPECIAL + 52 - 4*stm, 0);\r
                if(msp != old) goto extractMove; // one or more e.p. capture were generated\r
            }\r
-if(PATH) printf("# autofail=%d\n", autoFail);\r
-           if(autoFail) { // non-captures cannot auto-fail; flush queued captures first\r
-if(PATH) printf("# autofail end (%d-%d)\n", firstMove, msp);\r
-             autoFail = 0; curMove = firstMove - 1; continue; // release stashed moves for search\r
-           }\r
-           phase = 4; // out of victims: all captures generated\r
          case 4: // dubious captures\r
 #if 0\r
            while( dubious < framePtr + 250 ) // add dubious captures back to move stack\r
@@ -2042,6 +2043,7 @@ if(PATH) printf("%d:%2d:%d %3d %6x %-10s %6d %6d  (%d)\n", level, depth, iterDep
     if(lmr && bestScore <= alpha && iterDep == depth)\r
       depth++, lmr--; // self-deepen on fail-low reply to late move by lowering reduction\r
 #endif\r
+    if(stalemate && bestScore == -INF && !inCheck) bestScore = 0; // stalemate\r
 #ifdef HASH\r
     // hash store\r
     hashTable[index].lock[hit]  = hashKeyH;\r
@@ -2591,9 +2593,13 @@ pboard(board);
             engineSide = NONE;          // so stop playing\r
             PrintResult(stm, score);\r
           } else {\r
+            MOVE f, pMove = move;\r
+            if((move & SQUARE) >= SPECIAL && p[board[f = move>>SQLEN & SQUARE]].value == 80) { // e.p. capture\r
+              pMove = move & ~SQUARE | f + toList[(move & SQUARE) - SPECIAL]; // print as a single move\r
+            }\r
             stm = MakeMove2(stm, move);  // assumes MakeMove returns new side to move\r
             gameMove[moveNr++] = move;   // remember game\r
-            printf("move %s\n", MoveToText(move, 1));\r
+            printf("move %s\n", MoveToText(pMove, 1));\r
             listEnd = 0;\r
             continue;                    // go check if we should ponder\r
           }\r