Move input and procesing time, otim to separate routine
[hachu.git] / hachu.c
diff --git a/hachu.c b/hachu.c
index c9350ae..2f4a767 100644 (file)
--- a/hachu.c
+++ b/hachu.c
@@ -18,6 +18,7 @@
 \r
 #define HASH\r
 #define KILLERS\r
+#define NULLMOVE\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -1633,10 +1634,10 @@ if(flag && depth>= 0) printf("phase=%d: first/curr/last = %d / %d / %d\n", phase
              bestScore = curEval; resDep = QSdepth;\r
              if(bestScore >= beta || depth < -1) goto cutoff;\r
            }\r
-#if 0\r
-           if(curEval >= beta) {\r
+#ifdef NULLMOVE\r
+           else if(curEval >= beta) {\r
              stm ^= WHITE;\r
-             score = -Search(-beta, -iterAlpha, -difEval, depth-3, promoSuppress & SQUARE, ABSENT);\r
+             score = -Search(-beta, 1-beta, -difEval, depth > 3 ? depth-3 : 0, promoSuppress & SQUARE, ABSENT);\r
              stm ^= WHITE;\r
              if(score >= beta) { msp = oldMSP; retDep += 3; return score + (score < curEval); }\r
            }\r
@@ -2078,6 +2079,21 @@ ReadSquare (char *p, int *sqr)
   return 2 + (r + ONE > 9);\r
 }\r
 \r
+int listStart, listEnd;\r
+char boardCopy[BSIZE];\r
+\r
+void\r
+ListMoves ()\r
+{ // create move list on move stack\r
+  int i;\r
+  for(i=0; i< BSIZE; i++) boardCopy[i] = !!board[i];\r
+MapFromScratch(attacks);\r
+  postThinking--; repCnt = 0; tlim1 = tlim2 = 1e8; msp = 0;\r
+  Search(-INF-1, INF+1, 0, 1, sup1 & ~PROMOTE, sup2);\r
+  postThinking++;\r
+  listStart = retFirst; listEnd = msp = retMSP;\r
+}\r
+\r
 MOVE\r
 ParseMove (char *moveText)\r
 {\r
@@ -2100,18 +2116,15 @@ ParseMove (char *moveText)
   ret = f<<SQLEN | t2;\r
   if(*moveText != '\n' && *moveText != '=') ret |= PROMOTE;\r
 printf("# suppress = %c%d\n", sup1%BW+'a', sup1/BW);\r
-MapFromScratch(attacks);\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
+//  ListMoves();\r
+  for(i=listStart; i<listEnd; i++) {\r
     if(moveStack[i] == INVALID) continue;\r
     if(c == '@' && (moveStack[i] & SQUARE) == (moveStack[i] >> SQLEN & SQUARE)) break; // any null move matches @@@@\r
     if((moveStack[i] & (PROMOTE | DEFER-1)) == ret) break;\r
     if((moveStack[i] & DEFER-1) == ret) deferred = i; // promoted version of entered non-promotion is legal\r
   }\r
-printf("# moveNr = %d in {%d,%d}\n", i, retFirst, retMSP);\r
-  if(i>=retMSP) {  // no exact match\r
+printf("# moveNr = %d in {%d,%d}\n", i, listStart, listEnd);\r
+  if(i>=listEnd) { // no exact match\r
     if(deferred) { // but maybe non-sensical deferral\r
       int flags = p[board[f]].promoFlag;\r
 printf("# deferral of %d\n", deferred);\r
@@ -2122,8 +2135,8 @@ printf("# deferral of %d\n", deferred);
        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-50, moveStack[i], ret, MoveToText(moveStack[i], 0));\r
+    if(i >= listEnd) {\r
+      for(i=listStart; i<listEnd; 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
         if(repeatMove[i] & 1<<24) reason = (repeatMove[i] & 1<<25 ? "Distant capture of protected Lion" : "Counterstrike against Lion");\r
@@ -2134,7 +2147,7 @@ printf("# deferral of %d\n", deferred);
 }\r
     }\r
   }\r
-  return (i >= retMSP ? INVALID : moveStack[i]);\r
+  return (i >= listEnd ? INVALID : moveStack[i]);\r
 }\r
 \r
 void\r
@@ -2144,32 +2157,25 @@ Highlight(char *coords)
   char b[BSIZE], buf[2000], *q;\r
   for(i=0; i<bsize; i++) b[i] = 0;\r
   ReadSquare(coords, &sqr);\r
-MapFromScratch(attacks);\r
-//pmap(attacks, WHITE);\r
-//pmap(attacks, BLACK);\r
-//flag=1;\r
-  postThinking--; repCnt = 0;\r
-  Search(-INF-1, INF+1, 0, 1, sup1 & ~PROMOTE, sup2);\r
-  postThinking++;\r
-flag=0;\r
-  for(i=retFirst; i<retMSP; i++) {\r
+//  ListMoves();\r
+  for(i=listStart; i<listEnd; i++) {\r
     if(sqr == (moveStack[i]>>SQLEN & SQUARE)) {\r
       int t = moveStack[i] & SQUARE;\r
       if(t >= SPECIAL) continue;\r
-      b[t] = (board[t] == EMPTY ? 'Y' : 'R'); cnt++;\r
+      b[t] = (!boardCopy[t] ? 'Y' : 'R'); cnt++;\r
     }\r
   }\r
   if(!cnt) { // no moves from given square\r
     if(sqr != lastPut) return; // refrain from sending empty FEN\r
     // we lifted a piece for second leg of move\r
-    for(i=retFirst; i<retMSP; i++) {\r
+    for(i=listStart; i<listEnd; i++) {\r
       if(lastLift == (moveStack[i]>>SQLEN & SQUARE)) {\r
        int e, t = moveStack[i] & SQUARE;\r
        if(t < SPECIAL) continue; // only special moves\r
        e = lastLift + epList[t - SPECIAL]; // decode\r
        t = lastLift + toList[t - SPECIAL];\r
        if(e != sqr) continue;\r
-       b[t] = (board[t] == EMPTY ? 'Y' : 'R'); cnt++;\r
+       b[t] = (!boardCopy[t] ? 'Y' : 'R'); cnt++;\r
       }\r
     }\r
     if(!cnt) return;\r
@@ -2238,6 +2244,25 @@ printf("# setup done");fflush(stdout);
       else printf("0-1%s\n", tail);\r
     }\r
 \r
+    void GetLine(int root)\r
+    {\r
+      int i, c;\r
+      while(1) {\r
+        // wait for input, and read it until we have collected a complete line\r
+        for(i = 0; (inBuf[i] = c = getchar()) != '\n'; i++) if(c == EOF || i>7997) exit(0);\r
+        inBuf[i+1] = 0;\r
+\r
+        // extract the first word\r
+        sscanf(inBuf, "%s", command);\r
+        if(!strcmp(command, "otim"))    { continue; } // do not start pondering after receiving time commands, as move will follow immediately\r
+        if(!strcmp(command, "time"))    { sscanf(inBuf, "time %d", &timeLeft); continue; }\r
+        if(!strcmp(command, "put"))     { ReadSquare(inBuf+4, &lastPut); continue; }  // ditto\r
+        if(!strcmp(command, "."))       { inBuf[0] = 0; return; } // ignore for now\r
+        if(!strcmp(command, "lift"))    { inBuf[0] = 0; Highlight(inBuf+5); return; } // treat here\r
+        return;\r
+      }\r
+    }\r
+\r
     main()\r
     {\r
       int engineSide=NONE;                     // side played by engine\r
@@ -2253,6 +2278,8 @@ printf("# setup done");fflush(stdout);
 \r
         fflush(stdout);                 // make sure everything is printed before we do something that might take time\r
 \r
+        if(listEnd == 0) ListMoves();   // always maintain a list of legal moves in root position\r
+\r
         if(stm == engineSide) {         // if it is the engine's turn to move, set it thinking, and let it move\r
      \r
 pboard(board);\r
@@ -2279,6 +2306,7 @@ pboard(board);
             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
+            listEnd = 0;\r
           }\r
         }\r
 \r
@@ -2298,22 +2326,14 @@ pboard(board);
           }\r
         }\r
 \r
-      noPonder:\r
-        // wait for input, and read it until we have collected a complete line\r
-        for(i = 0; (inBuf[i] = getchar()) != '\n'; i++);\r
-        inBuf[i+1] = 0;\r
-\r
-        // extract the first word\r
-        sscanf(inBuf, "%s", command);\r
-printf("in: %s\n", command);\r
+        fflush(stdout);         // make sure everything is printed before we do something that might take time\r
+        if(!*inBuf) GetLine(1); // takes care of time and otim commands\r
 \r
         // recognize the command,and execute it\r
         if(!strcmp(command, "quit"))    { break; } // breaks out of infinite loop\r
         if(!strcmp(command, "force"))   { engineSide = NONE;    continue; }\r
         if(!strcmp(command, "analyze")) { engineSide = ANALYZE; continue; }\r
         if(!strcmp(command, "exit"))    { engineSide = NONE;    continue; }\r
-        if(!strcmp(command, "otim"))    { goto noPonder; } // do not start pondering after receiving time commands, as move will follow immediately\r
-        if(!strcmp(command, "time"))    { sscanf(inBuf, "time %d", &timeLeft); goto noPonder; }\r
         if(!strcmp(command, "level"))   {\r
           int min, sec=0;\r
           sscanf(inBuf, "level %d %d %d", &mps, &min, &inc) == 3 ||  // if this does not work, it must be min:sec format\r
@@ -2335,36 +2355,18 @@ printf("in: %s\n", command);
           if(sscanf(inBuf+7, "Contempt=%d", &contemptFactor) == 1) continue;\r
           continue;\r
         }\r
-        if(!strcmp(command, "variant")) {\r
-          for(i=0; i<7; i++) {\r
-            sscanf(inBuf+8, "%s", command);\r
-            if(!strcmp(variants[i].name, command)) {\r
-              Init(curVarNr = i); stm = Setup2(NULL); break;\r
-            }\r
-         }\r
-          continue;\r
-        }\r
         if(!strcmp(command, "sd"))      { sscanf(inBuf, "sd %d", &maxDepth);    continue; }\r
         if(!strcmp(command, "st"))      { sscanf(inBuf, "st %d", &timePerMove); continue; }\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"))     {\r
-          engineSide = BLACK; Init(V_CHESS); stm = Setup2(NULL); maxDepth = MAXPLY; randomize = OFF; curVarNr = comp = 0;\r
-          continue;\r
-        }\r
-        if(!strcmp(command, "setboard")){ engineSide = NONE;  Init(curVarNr); 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, "undo"))    { stm = TakeBack(1); continue; }\r
-        if(!strcmp(command, "remove"))  { stm = TakeBack(2); continue; }\r
         if(!strcmp(command, "go"))      { engineSide = stm;  continue; }\r
         if(!strcmp(command, "post"))    { postThinking = ON; continue; }\r
         if(!strcmp(command, "nopost"))  { postThinking = OFF;continue; }\r
         if(!strcmp(command, "random"))  { randomize = ON;    continue; }\r
         if(!strcmp(command, "hint"))    { if(ponderMove != INVALID) printf("Hint: %s\n", MoveToText(ponderMove, 0)); continue; }\r
-        if(!strcmp(command, "lift"))    { Highlight(inBuf+5); continue; }\r
-        if(!strcmp(command, "put"))     { ReadSquare(inBuf+4, &lastPut); continue; }\r
         if(!strcmp(command, "book"))    {  continue; }\r
        // non-standard commands\r
         if(!strcmp(command, "p"))       { pboard(board); continue; }\r
@@ -2380,7 +2382,7 @@ printf("in: %s\n", command);
         if(!strcmp(command, "accepted")){ continue; }\r
         if(!strcmp(command, "rejected")){ continue; }\r
         if(!strcmp(command, "result"))  { continue; }\r
-        if(!strcmp(command, "hover"))   {  continue; }\r
+        if(!strcmp(command, "hover"))   { continue; }\r
         if(!strcmp(command, ""))  {  continue; }\r
         if(!strcmp(command, "usermove")){\r
           int move = ParseMove(inBuf+9);\r
@@ -2390,11 +2392,28 @@ pboard(board);
             if(comp) PrintResult(stm, -INF); // against computer: claim\r
           } else {\r
             stm = MakeMove2(stm, move);\r
-            ponderMove = INVALID;\r
+            ponderMove = INVALID; listEnd = 0;\r
             gameMove[moveNr++] = move;  // remember game\r
           }\r
           continue;\r
         }\r
+        listEnd = 0;\r
+        if(!strcmp(command, "new"))     {\r
+          engineSide = BLACK; Init(V_CHESS); stm = Setup2(NULL); maxDepth = MAXPLY; randomize = OFF; curVarNr = comp = 0;\r
+          continue;\r
+        }\r
+        if(!strcmp(command, "variant")) {\r
+          for(i=0; i<7; i++) {\r
+            sscanf(inBuf+8, "%s", command);\r
+            if(!strcmp(variants[i].name, command)) {\r
+              Init(curVarNr = i); stm = Setup2(NULL); break;\r
+            }\r
+         }\r
+          continue;\r
+        }\r
+        if(!strcmp(command, "setboard")){ engineSide = NONE;  Init(curVarNr); stm = Setup2(inBuf+9); continue; }\r
+        if(!strcmp(command, "undo"))    { stm = TakeBack(1); continue; }\r
+        if(!strcmp(command, "remove"))  { stm = TakeBack(2); continue; }\r
         printf("Error: unknown command\n");\r
       }\r
     }\r