/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * 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 #include #include 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: */