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