Commit | Line | Data |
---|---|---|
cb290b32 C |
1 | |
2 | /* This file contains code for X-CHESS. | |
3 | Copyright (C) 1986 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of X-CHESS. | |
6 | ||
7 | X-CHESS is distributed in the hope that it will be useful, | |
8 | but WITHOUT ANY WARRANTY. No author or distributor | |
9 | accepts responsibility to anyone for the consequences of using it | |
10 | or for whether it serves any particular purpose or works at all, | |
11 | unless he says so in writing. Refer to the X-CHESS General Public | |
12 | License for full details. | |
13 | ||
14 | Everyone is granted permission to copy, modify and redistribute | |
15 | X-CHESS, but only under the conditions described in the | |
16 | X-CHESS General Public License. A copy of this license is | |
17 | supposed to have been given to you along with X-CHESS so you | |
18 | can know your rights and responsibilities. It should be in a | |
19 | file named COPYING. Among other things, the copyright notice | |
20 | and this notice must be preserved on all copies. */ | |
21 | ||
22 | ||
23 | /* RCS Info: $Revision: 1.2 $ on $Date: 86/11/23 17:18:10 $ | |
24 | * $Source: /users/faustus/xchess/RCS/program.c,v $ | |
25 | * Copyright (c) 1986 Wayne A. Christopher, U. C. Berkeley CAD Group | |
26 | * Permission is granted to do anything with this code except sell it | |
27 | * or remove this message. | |
28 | * | |
29 | * The interface to whichever chess playing program we are using... | |
30 | */ | |
31 | ||
32 | #include "xchess.h" | |
33 | #include <signal.h> | |
34 | #include <sys/time.h> | |
35 | ||
36 | static int pid; | |
37 | static FILE *from; | |
38 | static FILE *to; | |
39 | static bool easy = 1; | |
40 | ||
41 | bool | |
42 | program_init(name) | |
43 | char *name; | |
44 | { | |
45 | int toprog[2], fromprog[2]; | |
46 | char buf[BSIZE]; | |
47 | char time[10]; | |
48 | char moves[10]; | |
49 | ||
50 | pipe(toprog); | |
51 | pipe(fromprog); | |
52 | ||
53 | if (!(pid = fork())) { | |
54 | /* Start up the program. */ | |
55 | dup2(toprog[0], 0); | |
56 | dup2(fromprog[1], 1); | |
57 | close(toprog[0]); | |
58 | close(toprog[1]); | |
59 | close(fromprog[0]); | |
60 | close(fromprog[1]); | |
61 | sprintf (time, "%d", timeunit/60); | |
62 | sprintf (moves, "%d", movesperunit); | |
63 | if (proghost) | |
64 | execl("/usr/ucb/rsh", "rsh", proghost, name, | |
65 | moves, time, | |
66 | (char *) NULL); | |
67 | else | |
68 | execl(name, name, moves, time, (char *) NULL); | |
69 | perror(name); | |
70 | exit(1); | |
71 | } | |
72 | ||
73 | close(toprog[0]); | |
74 | close(fromprog[1]); | |
75 | ||
76 | from = fdopen(fromprog[0], "r"); | |
77 | setbuf(from, NULL); | |
78 | to = fdopen(toprog[1], "w"); | |
79 | setbuf(to, NULL); | |
80 | ||
81 | /* Get the first line... */ | |
82 | fgets(buf, BSIZE, from); | |
83 | if (debug) | |
84 | fprintf(stderr, "program says %s", buf); | |
85 | if (blackflag) { | |
86 | fputs("switch\n", to); | |
87 | fflush(to); | |
88 | fgets(buf, BSIZE, from); | |
89 | if (debug) | |
90 | fprintf(stderr, "program says %s", buf); | |
91 | message_add(win1, "GNU Chess playing white\n", false); | |
92 | } else | |
93 | message_add(win1, "GNU Chess playing black\n", false); | |
94 | ||
95 | return (true); | |
96 | } | |
97 | ||
98 | void | |
99 | program_end() | |
100 | { | |
101 | fclose(from); | |
102 | fclose(to); | |
103 | kill(pid, SIGTERM); | |
104 | return; | |
105 | } | |
106 | ||
107 | void | |
108 | program_send(m) | |
109 | move *m; | |
110 | { | |
111 | char buf[BSIZE]; | |
112 | ||
113 | if ((m->type == MOVE) || (m->type == CAPTURE)) | |
114 | sprintf(buf, "%c%d%c%d\n", 'a' + m->fromx, SIZE - m->fromy, | |
115 | 'a' + m->tox, SIZE - m->toy); | |
116 | else if (m->type == KCASTLE) | |
117 | strcpy(buf, (m->piece.color == WHITE) ? "e1g1\n" : "e8g8\n"); | |
118 | else if (m->type == QCASTLE) | |
119 | strcpy(buf, (m->piece.color == WHITE) ? "e1c1\n" : "e8c8\n"); | |
120 | ||
121 | if (debug) | |
122 | fprintf(stderr, "sending program %s", buf); | |
123 | if (!easy) | |
124 | kill (pid, SIGINT); | |
125 | ||
126 | fputs(buf, to); | |
127 | fflush(to); | |
128 | ||
129 | /* One junk line... */ | |
130 | fgets(buf, BSIZE, from); | |
131 | if (debug) | |
132 | fprintf(stderr, "program says %s", buf); | |
133 | return; | |
134 | } | |
135 | ||
136 | move * | |
137 | program_get() | |
138 | { | |
139 | int rfd = (1 << fileno(from)), wfd = 0, xfd = 0; | |
140 | static struct timeval notime = { 0, 0 }; | |
141 | char buf[BSIZE], *s; | |
142 | move *m; | |
143 | int i; | |
144 | ||
145 | /* Do a poll... */ | |
146 | ||
147 | if (!(i = select(32, &rfd, &wfd, &xfd, ¬ime)) && | |
148 | !from->_cnt) { /* Bad stuff... */ | |
149 | if (debug) | |
150 | fprintf(stderr, "poll: nothing\n"); | |
151 | return (NULL); | |
152 | } | |
153 | if (i == -1) { | |
154 | perror("select"); | |
155 | return (NULL); | |
156 | } | |
157 | ||
158 | fgets(buf, BSIZE, from); | |
159 | if (*buf == '\n' || *buf == '\0') { | |
160 | message_add(win1, "program died", false); | |
161 | return (NULL); | |
162 | } | |
163 | ||
164 | if (debug) | |
165 | fprintf(stderr, "got from program %s", buf); | |
166 | ||
167 | for (s = buf; !isalpha(*s); s++) | |
168 | ; | |
169 | m = parse_imove(chessboard, s, nexttomove); | |
170 | if (m == NULL) | |
171 | return (NULL); | |
172 | ||
173 | if (!valid_move(m, chessboard)) { | |
174 | fprintf(stderr, "Error: move %s is invalid!!\n", buf); | |
175 | return (NULL); | |
176 | } | |
177 | ||
178 | /* | |
179 | fgets(buf, BSIZE, from); | |
180 | if (debug) | |
181 | fprintf(stderr, "program says %s", buf); | |
182 | */ | |
183 | message_add(win1, buf, false); | |
184 | return (m); | |
185 | } | |
186 | ||
187 | void | |
188 | program_undo() | |
189 | { | |
190 | fputs("undo\n", to); | |
191 | return; | |
192 | } | |
193 | void | |
194 | program_easy (mode) | |
195 | bool mode; | |
196 | ||
197 | { | |
198 | fputs("easy\n", to); | |
199 | easy = mode; | |
200 | } |