135 lines
4.3 KiB
C
135 lines
4.3 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
|
|
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
|
|
* http://www.gnu.org/software/gnugo/ for more information. *
|
|
* *
|
|
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
|
|
* 2008 and 2009 by the Free Software Foundation. *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU General Public License as *
|
|
* published by the Free Software Foundation - version 3 *
|
|
* or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License in file COPYING for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public *
|
|
* License along with this program; if not, write to the Free *
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
|
* Boston, MA 02111, USA. *
|
|
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/* This program uses two pipes to communicate with the
|
|
* GNU Go client. To an external client it appears to
|
|
* be a gtp engine. It accomplishes this by intercepting
|
|
* gtp commands and passing them on to GNU Go.
|
|
*
|
|
* This program in and of itself is not useful but it
|
|
* can be the basis of useful programs. Example: hack
|
|
* in gmp.c and get a gtp / gmp mediator.
|
|
*
|
|
* Pipe a: client --> gnugo
|
|
* Pipe b: gnugo --> client
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
void error(const char *msg);
|
|
#define TELL_GNUGO(x) if (verbose) fprintf(stderr, "%s", x); \
|
|
if (fprintf(to_gnugo_stream, "%s", x) < 0) \
|
|
error ("can't write command in to_gnugo_stream"); \
|
|
fflush(to_gnugo_stream);
|
|
#define ASK_GNUGO(x) if (!fgets(x, 128, from_gnugo_stream)) \
|
|
error("can't get response");
|
|
int
|
|
main()
|
|
{
|
|
int pfd_a[2];
|
|
int pfd_b[2];
|
|
char gnugo_line[128], client_line[128];
|
|
int length = 0;
|
|
int verbose = 1;
|
|
FILE *to_gnugo_stream, *from_gnugo_stream;
|
|
|
|
if (pipe(pfd_a) == -1)
|
|
error("can't open pipe a");
|
|
if (pipe(pfd_b) == -1)
|
|
error("can't open pipe b");
|
|
switch (fork()) {
|
|
case -1:
|
|
error("fork failed (try chopsticks)");
|
|
case 0:
|
|
/* Attach pipe a to stdin */
|
|
if (dup2(pfd_a[0], 0) == -1)
|
|
error("dup pfd_a[0] failed");
|
|
/* attach pipe b to stdout" */
|
|
if (dup2(pfd_b[1], 1) == -1)
|
|
error("dup pfd_b[1] failed");
|
|
execlp("gnugo", "gnugo", "--mode", "gtp", "--quiet", NULL);
|
|
error("execlp failed");
|
|
}
|
|
/* We use stderr to communicate with the client since stdout is needed. */
|
|
/* Attach pipe a to to_gnugo_stream */
|
|
to_gnugo_stream = fdopen(pfd_a[1], "w");
|
|
/* Attach pipe b to from_gnugo_stream */
|
|
from_gnugo_stream = fdopen(pfd_b[0], "r");
|
|
|
|
while (1) {
|
|
int length = 0;
|
|
if (!fgets(client_line, 128, stdin)
|
|
|| !strncmp(client_line, "quit", 4)) {
|
|
TELL_GNUGO("quit\n");
|
|
return 1;
|
|
}
|
|
if (!strncmp(client_line, "genmove_black", 13)) {
|
|
char *token;
|
|
const char delimiters[] = " \t\r\n";
|
|
float value1, value2;
|
|
|
|
TELL_GNUGO("top_moves_black\n");
|
|
ASK_GNUGO(gnugo_line);
|
|
token = strtok(gnugo_line, delimiters);
|
|
token = strtok(NULL, delimiters);
|
|
TELL_GNUGO("black ");
|
|
TELL_GNUGO(token);
|
|
TELL_GNUGO("\n");
|
|
ASK_GNUGO(gnugo_line);
|
|
while (length != 1) {
|
|
ASK_GNUGO(gnugo_line);
|
|
length = strlen(gnugo_line);
|
|
printf(gnugo_line);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
else {
|
|
TELL_GNUGO(client_line);
|
|
while (length != 1) {
|
|
ASK_GNUGO(gnugo_line);
|
|
length = strlen(gnugo_line);
|
|
printf(gnugo_line);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
error(const char *msg)
|
|
{
|
|
fprintf(stderr, "vanilla: %s\n", msg);
|
|
abort();
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Local Variables:
|
|
* tab-width: 8
|
|
* c-basic-offset: 2
|
|
* End:
|
|
*/
|