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
program_init(name)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
program_end()99 program_end()
100 {
101 fclose(from);
102 fclose(to);
103 kill(pid, SIGTERM);
104 return;
105 }
106
107 void
program_send(m)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 *
program_get()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
program_undo()188 program_undo()
189 {
190 fputs("undo\n", to);
191 return;
192 }
193 void
program_easy(mode)194 program_easy (mode)
195 bool mode;
196
197 {
198 fputs("easy\n", to);
199 easy = mode;
200 }
201