xref: /386bsd/usr/src/games/chess/Xchess/record.c (revision a2142627)
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.4 $ on $Date: 86/11/23 17:18:20 $
24  *           $Source: /users/faustus/xchess/RCS/record.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  * Deal with recording moves.
30  */
31 
32 #include "xchess.h"
33 
34 #undef smartass
35 
36 bool record_english = true;
37 char *record_file = DEF_RECORD_FILE;
38 int movenum = 0;
39 bool saveflag = false;
40 
41 static char *colnames[] = { "qr", "qn", "qb", "q", "k", "kb", "kn", "kr" } ;
42 static char *pcnames[] = { "P", "R", "N", "B", "Q", "K" } ;
43 
44 static char *movestring();
45 static char *tstring();
46 static FILE *backup;
47 
48 #define RECORD_HEADER	"\n1    XChess Game Record0\n"
49 
50 void
record_init(win)51 record_init(win)
52 	windata *win;
53 {
54 	int i;
55 
56 	i = XTextWidth(win->medium, RECORD_HEADER,
57 		       sizeof(RECORD_HEADER) - 1);
58 	i = (40 * win->small->max_bounds.width - i *
59 	     win->medium->max_bounds.width) /
60 			win->medium->max_bounds.width / 2;
61 	TxtGrab(win->display, win->recwin, "xchess", win->small, win->textback.pixel,
62 			win->textcolor.pixel, win->cursorcolor.pixel);
63 	TxtAddFont(win->display, win->recwin, 1, win->medium, win->textcolor.pixel);
64 	for (; i > 0; i++)
65 		TxtWriteStr(win->display, win->recwin, " ");
66 	TxtWriteStr(win->display, win->recwin, RECORD_HEADER);
67 
68 	if (saveflag) {
69 		if (!(backup = fopen(record_file, "w"))) {
70 			perror(record_file);
71 			saveflag = false;
72 		} else {
73 			fprintf(backup, "X Chess -- %s\n", datestring());
74 			if (dispname2)
75 				fprintf(backup, "\tWhite on %s, black on %s\n",
76 						dispname1, dispname2);
77 			else
78 				fprintf(backup, "\tGame played on %s\n",
79 						dispname1);
80 			fprintf(backup, "\t%s\n", record_english ? "english" :
81 					"algebraic");
82 			fflush(backup);
83 		}
84 	}
85 
86 	movenum = 0;
87 	return;
88 }
89 
90 void
record_reset()91 record_reset()
92 {
93 	TxtWriteStr(win1->display, win1->recwin, "\n\n1    New Game0\n\n");
94 	if (!oneboard) {
95 		TxtWriteStr(win2->display, win2->recwin, "\n\n1    New Game0\n\n");
96 	}
97 	movenum = 0;
98 	if (saveflag) {
99 		fprintf(backup, "\n\nNew Game\n\n");
100 		fflush(backup);
101 	}
102 	return;
103 }
104 
105 void
record_end(s)106 record_end(s)
107 	char *s;
108 {
109 	char buf[BSIZE];
110 
111 	sprintf(buf, "\n%s\n", s);
112 	TxtWriteStr(win1->display, win1->recwin, s);
113 	if (!oneboard) {
114 		TxtWriteStr(win2->display, win2->recwin, s);
115 	}
116 	if (saveflag) {
117 		fprintf(backup, "\n%s\n", s);
118 		fprintf(backup, "Time: white: %s, ", tstring(whiteseconds));
119 		fprintf(backup, "black: %s\n", tstring(blackseconds));
120 		fclose(backup);
121 	}
122 	return;
123 }
124 
125 void
record_save()126 record_save()
127 {
128 	move *m;
129 	FILE *fp;
130 	int i;
131 	char *s;
132 
133 	if (!(fp = fopen(record_file, "w"))) {
134 		perror(record_file);
135 		return;
136 	}
137 	fprintf(fp, "X Chess -- %s\n", datestring());
138 	if (dispname2)
139 		fprintf(fp, "\tWhite on %s, black on %s\n",
140 				dispname1, dispname2);
141 	else
142 		fprintf(fp, "\tGame played on %s\n", dispname1);
143 	fprintf(fp, "\t%s\n", record_english ? "english" : "algebraic");
144 
145 	for (m = moves, i = 1; m; i++) {
146 		s = movestring(m);
147 		fprintf(fp, "%2d. %-16s ", i, s);
148 		m = m->next;
149 		if (m)
150 			s = movestring(m);
151 		else
152 			s = "";
153 		fprintf(fp, "%s\n", s);
154 		if (m)
155 			m = m->next;
156 	}
157 	fclose(fp);
158 	return;
159 }
160 
161 void
record_move(m)162 record_move(m)
163 	move *m;
164 {
165 	char *s, buf[BSIZE];
166 
167 	s = movestring(m);
168 
169 	if (m->piece.color == WHITE) {
170 		movenum++;
171 		sprintf(buf, "%2d. %-16s ", movenum, s);
172 	} else {
173 		sprintf(buf, "%s\n", s);
174 	}
175 	TxtWriteStr(win1->display, win1->recwin, buf);
176 	if (!oneboard) {
177 		TxtWriteStr(win2->display, win2->recwin, buf);
178 	}
179 	if (saveflag) {
180 		fprintf(backup, "%s", buf);
181 		fflush(backup);
182 	}
183 
184 	return;
185 }
186 
187 void
record_back()188 record_back()
189 {
190     extern move *lastmove;
191     move *m = lastmove;
192     char *s = movestring(m);
193     char buf[BSIZE];
194     long i;
195 
196     if (m->piece.color == WHITE) {
197 	sprintf(buf, "%2d. %-16s ", movenum, s);
198     } else {
199 	sprintf(buf, "%s\n", s);
200     }
201     s = buf;
202     for (i = 0; *s != '\0'; i++)
203 	*s++ = '';		/* control H, backspace */
204 
205     TxtWriteStr(win1->display, win1->recwin, buf);
206     if (!oneboard) {
207 	TxtWriteStr(win2->display, win2->recwin, buf);
208     }
209 
210     if (nexttomove == BLACK)
211 	movenum--;
212     if (saveflag) {
213 	fseek(backup, -i, 1);
214 	fflush(backup);
215     }
216 
217     return;
218 }
219 
220 static char *
movestring(m)221 movestring(m)
222 	move *m;
223 {
224 	int fy, ty;
225 	static char buf[BSIZE];
226 
227 	if (!record_english || (m->piece.color == WHITE)) {
228 		fy = SIZE - m->fromy;
229 		ty = SIZE - m->toy;
230 	} else {
231 		fy = m->fromy + 1;
232 		ty = m->toy + 1;
233 	}
234 
235 	switch (m->type) {
236 	    case MOVE:
237 		if (record_english)
238 			sprintf(buf, "%s/%s%d-%s%d%s", pcnames[(int) m->piece.
239 					type], colnames[m->fromx], fy,
240 					colnames[m->tox], ty, m->check ? "+" :
241 					"");
242 		else
243 			sprintf(buf, "%c%d%c%d", 'a' + m->fromx, fy, 'a' +
244 					m->tox, ty);
245 		break;
246 	    case CAPTURE:
247 		if (record_english)
248 			sprintf(buf, "%s/%s%dx%s/%s%d%s%s",
249 					pcnames[(int) m->piece.type],
250 					colnames[m->fromx], fy,
251 					pcnames[(int) m->taken.type],
252 					colnames[m->tox], ty,
253 					m->enpassant ? "e.p." : "",
254 					m->check ? "+" : "");
255 		else
256 			sprintf(buf, "%c%d%c%d", 'a' + m->fromx, fy, 'a' +
257 					m->tox, ty);
258 		break;
259 
260 	    case KCASTLE:
261 		if (record_english)
262 			sprintf(buf, "O-O%s", m->check ? "ch" : "");
263 		else if (m->piece.color == WHITE)
264 			strcpy(buf, "e1g1");
265 		else
266 			strcpy(buf, "e8g8");
267 		break;
268 
269 	    case QCASTLE:
270 		if (record_english)
271 			sprintf(buf, "O-O-O%s", m->check ? "ch" : "");
272 		else if (m->piece.color == WHITE)
273 			strcpy(buf, "e1c1");
274 		else
275 			strcpy(buf, "e8c8");
276 		break;
277 
278 	    default:
279 		sprintf(buf, "something strange");
280 		break;
281 	}
282 	if ((m->piece.type == PAWN) && (((m->piece.color == BLACK) &&
283 			(m->toy == 7)) || ((m->piece.color == WHITE) &&
284 			(m->toy == 0))))
285 		strcat(buf, "(Q)");
286 
287 #ifdef smartass
288 	if (!(random() % 50))
289 		strcat(buf, "?");
290 	else if (!(random() % 50))
291 		strcat(buf, "!");
292 	else if (!(random() % 500))
293 		strcat(buf, "???");
294 	else if (!(random() % 500))
295 		strcat(buf, "!!!");
296 #endif smartass
297 
298 	return (buf);
299 }
300 
301 static char *
tstring(s)302 tstring(s)
303 	int s;
304 {
305 	static char buf[64];
306 
307 	if (s > 3600)
308 		sprintf(buf, "%dh %dm %ds", s / 3600, (s % 3600) / 60, s % 60);
309 	else if (s > 60)
310 		sprintf(buf, "%dm %ds", (s % 3600) / 60, s % 60);
311 	else
312 		sprintf(buf, "%ds", s);
313 	return (buf);
314 }
315 
316