X-Git-Url: http://winboard.nl/cgi-bin?p=uci2wb.git;a=blobdiff_plain;f=UCI2WB.c;h=c13ea347d0b6640c2b8f284992efd6725fdf2d32;hp=8dcc73416ddf58169b925919a6029d3bf460200d;hb=e7c084cff327333c02190799fc3803c1a2b4fe74;hpb=e5a0dfcb7ef1bd4450b235ce1405bc295a621036 diff --git a/UCI2WB.c b/UCI2WB.c index 8dcc734..c13ea34 100644 --- a/UCI2WB.c +++ b/UCI2WB.c @@ -1,6 +1,15 @@ -/************************* UCI2WB by H.G.Muller ****************************/ - -#define VERSION "1.10" +/****************************************************************************/ +/* UCI2WB by H.G.Muller */ +/* */ +/* UCI2WB is an adapter to run engines that communicate in various dialects */ +/* of the Universal Chess Interface in a GUI that supports XBoard protocol */ +/* (CECP). It supports UCI (when used for Xiangqi: the 'Cyclone dialect'), */ +/* as well as USI and UCCI when used with the flags -s or -x, respectively. */ +/* This version of UCI2WB is released under the GNU General Public License, */ +/* of which you should have received a copy together with this file. */ +/****************************************************************************/ + +#define VERSION "2.3" #include #include @@ -21,19 +30,21 @@ #include // Set VARIANTS for in WinBoard variant feature. (With -s option this will always be reset to use "shogi".) -# define VARIANTS "normal,xiangqi" +#define VARIANTS "normal,xiangqi" +#define STDVARS "chess,chess960,crazyhouse,threecheck,giveaway,atomic,seirawan,shogi,xiangqi" #define DPRINT if(debug) printf +#define EPRINT(X) { char f[999]; sprintf X; DPRINT("%s", f); fprintf(toE, "%s", f + 2*(*f == '#')); /* strip optional # prefix */ } #define WHITE 0 #define BLACK 1 #define NONE 2 #define ANALYZE 3 -char move[2000][10], checkOptions[8192], iniPos[256], hashOpt[20], pause, pondering, suspended, ponder, post, hasHash, c, sc='c', *suffix, *variants; -int mps, tc, inc, sTime, depth, myTime, hisTime, stm, computer = NONE, memory, oldMem=0, cores, moveNr, lastDepth, lastScore, startTime, debug; -int statDepth, statScore, statNodes, statTime, currNr, size, collect, nr, sm, inex, on[500]; -char currMove[20], moveMap[500][10], /* for analyze mode */ canPonder[20], threadOpt[20]; +char move[2000][10], checkOptions[8192], iniPos[256], hashOpt[20], pause, pondering, suspended, ponder, post, hasHash, c, sc='c', suffix[81], *variants, varOpt; +int mps, tc, inc, sTime, depth, myTime, hisTime, stm, computer = NONE, memory, oldMem=0, cores, moveNr, lastDepth, lastScore, startTime, debug, flob; +int statDepth, statScore, statNodes, statTime, currNr, size, collect, nr, sm, inex, on[500], frc, byo = -1, namOpt, comp; +char currMove[20], moveMap[500][10], /* for analyze mode */ canPonder[20], threadOpt[20], varList[8000]; char board[100]; // XQ board for UCCI char *nameWord = "name ", *valueWord = "value ", *wTime = "w", *bTime = "b", *wInc = "winc", *bInc = "binc", newGame; // keywords that differ in UCCI int unit = 1, drawOffer; @@ -42,6 +53,8 @@ FILE *toE, *fromE, *fromF; int pid; #ifdef WIN32 +char *strcasestr (char *p, char *q) { char *r = p; while(*r) *r = tolower(*r), r++; return strstr(p, q); } + WinPipe(HANDLE *hRd, HANDLE *hWr) { SECURITY_ATTRIBUTES saAttr; @@ -120,7 +133,7 @@ Play(int nr) FromFEN(iniPos + 4); // in XQ iniPos always has just "fen " prefix for(i=0; i 0) { fprintf(toE, " movetime %d", sTime); DPRINT(" movetime %d", sTime); } else - if(mps) { fprintf(toE, " movestogo %d", mps*(nr/(2*mps)+1)-nr/2); DPRINT(" movestogo %d", mps*(nr/(2*mps)+1)-nr/2); } - if(inc && !suffix) { fprintf(toE, " %s %d %s %d", wInc, inc, bInc, inc); DPRINT(" %s %d %s %d", wInc, inc, bInc, inc); } - if(depth > 0) { fprintf(toE, " depth %d", depth); DPRINT(" depth %d", depth); } - if(suffix) { fprintf(toE, suffix, inc); DPRINT(suffix, inc); } - fprintf(toE, "\n"); DPRINT("\n"); + int t = (flob ? inc + myTime/40 : 1000*byo*(byo>0)); // byoyomi time + if(sc == 'x') black = 1; else drawOffer = 0;// in UCCI 'black' refers to us and 'white' to opponent + if(!x && drawOffer) ponder = " draw", drawOffer = 0; //pass draw offer only when not pondering + EPRINT((f, "# go%s %stime %d %stime %d", ponder, bTime, (black ? myTime : hisTime) - t, wTime, (!black ? myTime : hisTime) - t)) + if(sTime > 0) EPRINT((f, " movetime %d", sTime)) else + if(mps) EPRINT((f, " movestogo %d", mps*(nr/(2*mps)+1)-nr/2)) + if(flob || byo >= 0) sprintf(suffix, " byoyomi %d", t); // for engines running purely on byoyomi + if(inc && !*suffix) EPRINT((f, " %s %d %s %d", wInc, inc, bInc, inc)) + if(depth > 0) EPRINT((f, " depth %d", depth)) + if(*suffix) EPRINT((f, suffix, inc)) + EPRINT((f, "\n")) } void @@ -150,7 +163,7 @@ StopPonder(int pondering) { if(!pondering) return; pause = 1; - fprintf(toE, "stop\n"); fflush(toE); DPRINT("# stop\n"); // note: 'pondering' remains set until engine acknowledges 'stop' with 'bestmove' + EPRINT((f, "# stop\n")) fflush(toE); // note: 'pondering' remains set until engine acknowledges 'stop' with 'bestmove' Sync(PAUSE); // wait for engine to acknowledge 'stop' with 'bestmove'. } @@ -164,9 +177,9 @@ LoadPos(int moveNr) stm = (!strstr(iniPos+4, " b ") ^ lastCapt & 1 ? 'w' : 'b'); sprintf(buf, "position fen %s", ToFEN(stm)); pos = buf; // send it as FEN (with "position" in UCCI!) } - fprintf(toE, "%s moves", pos); - DPRINT( "# %s moves", pos); - for(j=lastCapt; j 0) EPRINT((f, "# setoption name UCI_Chess960 value true\n")) } } else if(!strcmp(command, "undo") && (i=1) || !strcmp(command, "remove") && (i=2)) { - if(pondering || computer == ANALYZE) StopPonder(1); + if(pondering || computer == ANALYZE) StopPonder(1), searching = 0; moveNr = moveNr > i ? moveNr - i : 0; collect = (computer == ANALYZE); sm = 0; } else if(!strcmp(command, ".")) { @@ -463,7 +510,7 @@ GUI2Engine() inex = 1; line[strlen(line)-1] = sm = 0; // strip LF and clear sm flag for(i=1; i 1 && argv[1][0] == '-') { sc = argv[1][1]; argc--; argv++; } if(argc < 2) { printf("usage is: U%cI2WB [debug] [-s] []\n", sc-32); exit(-1); } if(argc > 2) dir = argv[2]; - if(argc > 3) suffix = argv[3]; + if(argc > 3) strncpy(suffix, argv[3], 80); if(sc == 'x') nameWord = valueWord = bTime = "", wTime = "opp", bInc = "increment", wInc = "oppincrement", unit = 1000; // switch to UCCI keywords + else if(sc == 'f' ) frc = -1, sc = 'c'; // UCI for unannounced Chess960 + else if(sc == 'n') sc = 'c'; // UCI for normal Chess // spawn engine proc if(StartEngine(argv[1], dir) != NO_ERROR) { perror(argv[1]), exit(-1); } @@ -603,7 +655,7 @@ main(int argc, char **argv) #ifdef WIN32 CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Engine2GUI, (LPVOID) NULL, 0, &thread_id); #else - { pthread_t t; signal(SIGINT, SIG_IGN); pthread_create(&t, NULL, Engine2GUI, NULL); } + { pthread_t t; signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); pthread_create(&t, NULL, Engine2GUI, NULL); } #endif // handle GUI->engine traffic in original thread