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