Implement UCCI
[uci2wb.git] / UCI2WB.c
index bd8a4f8..21aad7d 100644 (file)
--- a/UCI2WB.c
+++ b/UCI2WB.c
@@ -132,6 +132,7 @@ StartSearch(char *ponder)
        int x = (ponder[0] != 0);                   // during ponder stm is the opponent\r
        int black = (stm == BLACK ^ x ^ sc == 's'); // set if our color is what the engine calls black\r
        int nr = moveNr + x;                        // we ponder for one move ahead!\r
+       if(sc == 'x') black = 1;                    // in UCCI 'black' refers to us and 'white' to opponent\r
        fprintf(toE, "\ngo%s %stime %d %stime %d", ponder, bTime, black ? myTime : hisTime, wTime, !black ? myTime : hisTime);\r
        DPRINT(    "\n# go%s %stime %d %stime %d", ponder, bTime, black ? myTime : hisTime, wTime, !black ? myTime : hisTime);\r
        if(sTime > 0) { fprintf(toE, " movetime %d", sTime); DPRINT(" movetime %d", sTime); } else\r
@@ -154,10 +155,16 @@ StopPonder(int pondering)
 void\r
 LoadPos(int moveNr)\r
 {\r
-       int j;\r
-       fprintf(toE, "%s moves", iniPos);\r
-       DPRINT(    "# %s moves", iniPos);\r
-       for(j=0; j<moveNr; j++) { fprintf(toE, " %s", move[j]); DPRINT(" %s", move[j]); }\r
+       int j, lastCapt = 0; char *pos = iniPos, buf[200], stm;\r
+       if(sc == 'x') { // UCCI: send only reversible moves\r
+           lastCapt = Play(moveNr); // find last capture (returns -1 if none!)\r
+           Play(++lastCapt);        // reconstruct board after last capture\r
+           stm = (!strstr(iniPos+4, " b ") ^ lastCapt & 1 ? 'w' :  'b');\r
+           sprintf(buf, "position fen %s", ToFEN(stm)); pos = buf; // send it as FEN (with "position" in UCCI!)\r
+       }\r
+       fprintf(toE, "%s moves", pos);\r
+       DPRINT(    "# %s moves", pos);\r
+       for(j=lastCapt; j<moveNr; j++) { fprintf(toE, " %s", move[j]); DPRINT(" %s", move[j]); }\r
 }\r
 \r
 void\r
@@ -236,6 +243,7 @@ Engine2GUI()
            sscanf(line, "bestmove %s", move[moveNr++]);\r
            myTime -= (GetTickCount() - startTime)*1.02 + inc; // update own clock, so we can give correct wtime, btime with ponder\r
            if(mps && ((moveNr+1)/2) % mps == 0) myTime += tc; if(sTime) myTime = sTime; // new session or move starts\r
+\r
            stm = WHITE+BLACK - stm;\r
            // first start a new ponder search, if pondering is on and we have a move to ponder on\r
            if(p = strstr(line+9, "ponder")) {\r
@@ -286,7 +294,7 @@ Engine2GUI()
            if(p = strstr(line+6, " min "))  sscanf(p+1, "min %d", &min), *p = '\n';\r
            if(p = strstr(line+6, " max "))  sscanf(p+1, "max %d", &max), *p = '\n';\r
            if(p = strstr(line+6, " default "))  sscanf(p+1, "default %[^\n]*", val), *p = '\n';\r
-           if(p = strstr(line+6, " name ")) sscanf(p+1, "name %[^\n]*", name);\r
+           if(!(p = strstr(line+6, " name "))) p = line+1; sscanf(p+6, "%[^\n]", name); // 'name' is omitted in UCCI\r
            if(!strcmp(name, "Threads")) { strcpy(threadOpt, name); continue; }\r
            if(!strcmp(name, "Ponder") || !strcmp(name, "USI_Ponder")) { strcpy(canPonder, name); continue; }\r
            if(!strcmp(name, "Hash") || !strcmp(name, "USI_Hash")) {\r
@@ -319,7 +327,10 @@ Engine2GUI()
            if(sscanf(line, "id name %[^\n]", name) == 1) printf("feature myname=\"%s (U%cI2WB)\"\n", name, sc-32);\r
        }\r
        else if(!strcmp(command, "readyok")) { pause = 0; Sync(WAKEUP); } // resume processing of GUI commands\r
-       else if(sscanf(command, "u%ciok", &c)==1 && c==sc)   printf("feature smp=1 memory=%d done=1\n", hasHash), Sync(WAKEUP); // done with options\r
+       else if(sc == 'x'&& !strcmp(command, "ucciok") || sscanf(command, "u%ciok", &c)==1 && c==sc) {\r
+           printf("feature smp=1 memory=%d done=1\n", hasHash);\r
+           Sync(WAKEUP); // done with options\r
+       }\r
     }\r
 }\r
 \r
@@ -414,7 +425,7 @@ GUI2Engine()
            if(!variants) variants = sc=='s' ? "shogi,5x5+5_shogi" : VARIANTS;\r
            printf("feature variants=\"%s\" setboard=1 usermove=1 debug=1 ping=1 reuse=0 exclude=1 pause=1 done=0\n", variants);\r
            printf("feature option=\"UCI2WB debug output -check %d\"\n", debug);\r
-           fprintf(toE, "u%ci\n", sc); fflush(toE); // this prompts UCI engine for options\r
+           fprintf(toE, sc == 'x' ? "ucci\n" : "u%ci\n", sc); fflush(toE); // prompt UCI engine for options\r
            Sync(PAUSE); // wait for uciok\r
        }\r
        else if(!strcmp(command, "setboard")) {\r
@@ -574,6 +585,8 @@ main(int argc, char **argv)
        if(argc > 2) dir = argv[2];\r
         if(argc > 3) suffix = argv[3];\r
 \r
+        if(sc == 'x') nameWord = valueWord = bTime = "", wTime = "opp", bInc = "increment", wInc = "oppincrement", unit = 1000; // switch to UCCI keywords\r
+\r
        // spawn engine proc\r
        if(StartEngine(argv[1], dir) != NO_ERROR) { perror(argv[1]), exit(-1); }\r
 \r