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, ¬ime)) &&
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