xref: /original-bsd/games/chess/Xchess/program.c (revision cde01d6c)
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, &notime)) &&
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 }
201