Btw, I write a Max2WB adapter to be able to play the stand-alone versions of uMax and Toledo_Nanochess under WinBoard! This is possible, because they essentially use the same protocol now (producing a move when you enter an empty line, and relaying it by printing a new board.)
The only catch is that to make it work, the engine should not buffer its output. So in the Toledo sprogram I had to replace the 
putchar(l[...]); by 
write(1,l+(...),1); to achieve that. (That is 3 extra characters.) In uMax 1.6 I added an fflush(stdout); for now.
This makes them play automatically under Windows+Cygwin (and I guess also under Linux), but the adapter is dependent on the cygwin1.dll. To use the adapter, start WB with
-fcp "./Max2WB ./uMax1_6" -scp "./Max2WB ./Toledo"
This works, but, as I said, after some 15 moves Toledo crashes my system. (Of course they ignore the WinBoard TC settings; be sure to play without 
auto flag.)
Code: Select all
/**************************************************/
/*     Minimal Max2QH adapter by H.G. Muller      */
/**************************************************/
#include <stdio.h>
#include <signal.h>
char before[80], after[80];
FILE *f;
void ReadBoard(int inp, char *board)
{       // read 64 non-blank characters
        int i;
        char c, *oldBoard = board;
        for(i=0; i<64; i++) {
            do{ read(inp, &c, 1);
            } while(c == '\n' || c == ' ' || c == '\t' || c == '\r');
            *board++ = c;
        }
        fprintf(f, "E< '%s'\n", oldBoard); fflush(f);
}
void ProduceMove(int from, int to)
{
        int ifrom=-1, ito=-1, i;
        write(to, "\n", 1);      // send thinking command (empty line)
        ReadBoard(from, after);  // should respond with board;
        for(i=0; i<64; i++) {
            if(before[i] == after[i]) continue;
            if(after[i] == '.') {
                // from-square
                if(ifrom <= 0 || ifrom == 7 || ifrom == 070 || ifrom == 077)
                     ifrom = i;  // first one, or overwrite corner Rook
                else if(ifrom != 4 && ifrom != 074)
                     ifrom = 65; // must be e.p.
            } else {
                // if not empty after move, must be to-square
                if(ito < 0 || ito != 4 && ito != 074)
                     ito = i; // first one, or write King over Rook
            }
            if(ifrom == 65) ifrom = ito ^ 010;
        }
        printf("move %c%c%c%c\n", 'a'+(ifrom&7), '8'-(ifrom>>3),
                                  'a'+(ito&7),   '8'-(ito>>3));
        fflush(stdout);
}
main(int argc, char **argv)
{
        int toPipe[2], fromPipe[2], from_prog, to_prog, pid, pid2, i, j;
        char c, buf[256], command[256], *name;
        if(argc < 2)
            exit(0);   // first arg must be engine
        name = argv[1]; while(*name) name++;
        while(name-argv[1] > 0 && name[-1] != '\\' && name[-1] != '/') name--;
        /* OK, so we now send through to_prog, receive through from_prog */
        
        f = fopen("log", "w");
        {   /* cmain loop ommunicates to WinBoard */
            int ponderStateWB = 0;
            int ponderStateQH = 2;
            int forceMode = 0;
            setbuf(stdin, NULL);
            i = 0;
            while((c=getchar()) != EOF) {
                if(c == '\r') continue;
                if(c != '\n') { buf[i++] = c; continue; }
                buf[i] = 0;
                fprintf(f, "WB> %s\n", buf); fflush(f);
                sscanf(buf, "%s", command);
                if(!strcmp(command, "quit"))       // pass on & kill
                    close(to_prog),
                    close(from_prog),
                    kill(pid,  SIGKILL),
                    fclose(f),
                    exit(0);
                else if(!strcmp(command, "result")) // pass on & kill
                    close(to_prog),
                    close(from_prog),
                    kill(pid,  SIGKILL);
                else if(!strcmp(command, "protover"))
                    printf("feature myname=\"%s\" done=1\n", name),
                    fflush(stdout);
                else if(!strcmp(command, "go"))    // end force mode & think
                    forceMode=0,
                    ProduceMove(from_prog, to_prog);
                else if(!strcmp(command, "hard"))
                    ponderStateWB = 1;
                else if(!strcmp(command, "easy"))
                    ponderStateWB = 0;
                else if(!strcmp(command, "force")) // remember
                    forceMode = 1;
                else if(!strcmp(command, "new")) { // start new engine proc
                    /* close old pipes */
                    if(from_prog)close(from_prog);
                    if(to_prog)close(to_prog);
                    /* set up pipes */
                    pipe(toPipe);
                    pipe(fromPipe);
                    /* create engine */
                    if((pid = fork()) == 0)
                    {   /* child */
                        fclose(stderr);
                        close(toPipe[1]);
                        close(fromPipe[0]);
                        dup2(toPipe[0], 0);
                        dup2(fromPipe[1], 1);
                        if(toPipe[0] >= 2) close(toPipe[0]);
                        close(fromPipe[1]);
                        execv(argv[1], argv+1);
                        perror(argv[1]);
                        exit(1);
                    }
                    /* parent */
                    close(toPipe[0]);
                    close(fromPipe[1]);
                    from_prog = fromPipe[0];
                    to_prog   = toPipe[1];
                    forceMode = 0;
                    ReadBoard(from_prog, before);
                } else if((buf[4] == 0 || buf[5] == 0) &&
                        command[0] >= 'a' && command[0] <= 'h' &&
                        command[2] >= 'a' && command[2] <= 'h' &&
                        command[1] >= '1' && command[1] <= '8' &&
                        command[3] >= '1' && command[3] <= '8'   ) // pass on
                { /* move */
                    sprintf(command, "%c%c%c%c\n",
                                buf[0], buf[1], buf[2], buf[3]);
                    write(to_prog, command, 5);
                    ReadBoard(from_prog, before); // read board after forced move
                    if(!forceMode)     // go thinking if not in force mode
                        ProduceMove(from_prog, to_prog);
                }
                i = 0;
            }
        }
}