Commit | Line | Data |
---|---|---|
7eeb782e AT |
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ |
2 | * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see * | |
3 | * http://www.gnu.org/software/gnugo/ for more information. * | |
4 | * * | |
5 | * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * | |
6 | * 2008 and 2009 by the Free Software Foundation. * | |
7 | * * | |
8 | * This program is free software; you can redistribute it and/or * | |
9 | * modify it under the terms of the GNU General Public License as * | |
10 | * published by the Free Software Foundation - version 3 * | |
11 | * or (at your option) any later version. * | |
12 | * * | |
13 | * This program is distributed in the hope that it will be useful, * | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
16 | * GNU General Public License in file COPYING for more details. * | |
17 | * * | |
18 | * You should have received a copy of the GNU General Public * | |
19 | * License along with this program; if not, write to the Free * | |
20 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * | |
21 | * Boston, MA 02111, USA. * | |
22 | \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
23 | ||
24 | /* This program uses two pipes to communicate with the | |
25 | * GNU Go client. To an external client it appears to | |
26 | * be a gtp engine. It accomplishes this by intercepting | |
27 | * gtp commands and passing them on to GNU Go. | |
28 | * | |
29 | * This program in and of itself is not useful but it | |
30 | * can be the basis of useful programs. Example: hack | |
31 | * in gmp.c and get a gtp / gmp mediator. | |
32 | * | |
33 | * Pipe a: client --> gnugo | |
34 | * Pipe b: gnugo --> client | |
35 | */ | |
36 | ||
37 | #include <stdio.h> | |
38 | #include <unistd.h> | |
39 | #include <string.h> | |
40 | ||
41 | void error(const char *msg); | |
42 | #define TELL_GNUGO(x) if (verbose) fprintf(stderr, "%s", x); \ | |
43 | if (fprintf(to_gnugo_stream, "%s", x) < 0) \ | |
44 | error ("can't write command in to_gnugo_stream"); \ | |
45 | fflush(to_gnugo_stream); | |
46 | #define ASK_GNUGO(x) if (!fgets(x, 128, from_gnugo_stream)) \ | |
47 | error("can't get response"); | |
48 | int | |
49 | main() | |
50 | { | |
51 | int pfd_a[2]; | |
52 | int pfd_b[2]; | |
53 | char gnugo_line[128], client_line[128]; | |
54 | int length = 0; | |
55 | int verbose = 1; | |
56 | FILE *to_gnugo_stream, *from_gnugo_stream; | |
57 | ||
58 | if (pipe(pfd_a) == -1) | |
59 | error("can't open pipe a"); | |
60 | if (pipe(pfd_b) == -1) | |
61 | error("can't open pipe b"); | |
62 | switch (fork()) { | |
63 | case -1: | |
64 | error("fork failed (try chopsticks)"); | |
65 | case 0: | |
66 | /* Attach pipe a to stdin */ | |
67 | if (dup2(pfd_a[0], 0) == -1) | |
68 | error("dup pfd_a[0] failed"); | |
69 | /* attach pipe b to stdout" */ | |
70 | if (dup2(pfd_b[1], 1) == -1) | |
71 | error("dup pfd_b[1] failed"); | |
72 | execlp("gnugo", "gnugo", "--mode", "gtp", "--quiet", NULL); | |
73 | error("execlp failed"); | |
74 | } | |
75 | /* We use stderr to communicate with the client since stdout is needed. */ | |
76 | /* Attach pipe a to to_gnugo_stream */ | |
77 | to_gnugo_stream = fdopen(pfd_a[1], "w"); | |
78 | /* Attach pipe b to from_gnugo_stream */ | |
79 | from_gnugo_stream = fdopen(pfd_b[0], "r"); | |
80 | ||
81 | while (1) { | |
82 | int length = 0; | |
83 | if (!fgets(client_line, 128, stdin) | |
84 | || !strncmp(client_line, "quit", 4)) { | |
85 | TELL_GNUGO("quit\n"); | |
86 | return 1; | |
87 | } | |
88 | if (!strncmp(client_line, "genmove_black", 13)) { | |
89 | char *token; | |
90 | const char delimiters[] = " \t\r\n"; | |
91 | float value1, value2; | |
92 | ||
93 | TELL_GNUGO("top_moves_black\n"); | |
94 | ASK_GNUGO(gnugo_line); | |
95 | token = strtok(gnugo_line, delimiters); | |
96 | token = strtok(NULL, delimiters); | |
97 | TELL_GNUGO("black "); | |
98 | TELL_GNUGO(token); | |
99 | TELL_GNUGO("\n"); | |
100 | ASK_GNUGO(gnugo_line); | |
101 | while (length != 1) { | |
102 | ASK_GNUGO(gnugo_line); | |
103 | length = strlen(gnugo_line); | |
104 | printf(gnugo_line); | |
105 | fflush(stdout); | |
106 | } | |
107 | } | |
108 | else { | |
109 | TELL_GNUGO(client_line); | |
110 | while (length != 1) { | |
111 | ASK_GNUGO(gnugo_line); | |
112 | length = strlen(gnugo_line); | |
113 | printf(gnugo_line); | |
114 | fflush(stdout); | |
115 | } | |
116 | } | |
117 | } | |
118 | } | |
119 | ||
120 | void | |
121 | error(const char *msg) | |
122 | { | |
123 | fprintf(stderr, "vanilla: %s\n", msg); | |
124 | abort(); | |
125 | } | |
126 | ||
127 | ||
128 | ||
129 | /* | |
130 | * Local Variables: | |
131 | * tab-width: 8 | |
132 | * c-basic-offset: 2 | |
133 | * End: | |
134 | */ |