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;
}
}
}