Do you have any idea what causes the 'memory leak' in Toledo? Is it that 'main' reserves space for buffers, each time it is called? (And because 'main' is used as Search() in Toledo it is called really often!) Not having a separate routine for Search() might save some charcters, but this effect is quickly undone if you need all the buffer stuff to prevent it from crashing! (Which probaby forces you to include stdio.h as well...)
Can you also compile a blitz version of Toledo? You can make this by changing the '5' on the last line (3rd character) into '4'.
Note that Toledo tends to hang after a game, using full CPU. The adapter tries to kill it, but apparently this does not work.
The new Max2WB.c:
Code: Select all
/**************************************************/
/*        Max2WB adapter by H.G. Muller           */
/* Allows micro-Max stand-alone versions, as well */
/* as Toledo_nanochess to play under WinBoard     */
/* Use "Max2WB <egine> as WinBoard chess-program  */
/* name, where <engine> is the name of the engine */
/* executable file.                               */
/**************************************************/
#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] == '.') {
                // squre became empty: 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; // two fromSqr, and not K or R: must be e.p.
            } else {
                // if not empty after move, must be to-square
                if(ito < 0 || ito != 2 && ito != 072)
                     ito = i; // first one, or write King over Rook
            }
            if(ifrom == 65) ifrom = ito ^ 010; // calculate e.p. fromSqr
        }
        if(before[ifrom] != after[ito]) // piece changed: promotion
            printf("move %c%c%c%c%c\n", 'a'+(ifrom&7), '8'-(ifrom>>3),
                                        'a'+(ito&7),   '8'-(ito>>3),
                                        after[ito]|32);
        else
            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 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, "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 */ char c; int k;
                    if(c = buf[4]) {
                        k = buf[0]-'a'+('8'-buf[1])*8;
                        if(after[k]=='+' || after[k] == '*') // uMax
                             k = c=='q'?0:c=='r'?1:c=='b'?2:c=='n'?3:4;
                        else k = c=='q'?6:c=='r'?5:c=='b'?4:c=='n'?3:2;
                        sprintf(command, "%c%c%c%c%d\n",
                                buf[0], buf[1], buf[2], buf[3], k);
                        write(to_prog, command, 6);
                    } else { 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;
            }
        }
}





