1*41197Sbostic /*
2*41197Sbostic UNIX & MSDOS NON-DISPLAY, AND CHESSTOOL interface for Chess
3*41197Sbostic
4*41197Sbostic Revision: 4-25-88
5*41197Sbostic
6*41197Sbostic Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
7*41197Sbostic Copyright (c) 1988 John Stanback
8*41197Sbostic
9*41197Sbostic This file is part of CHESS.
10*41197Sbostic
11*41197Sbostic CHESS is distributed in the hope that it will be useful,
12*41197Sbostic but WITHOUT ANY WARRANTY. No author or distributor
13*41197Sbostic accepts responsibility to anyone for the consequences of using it
14*41197Sbostic or for whether it serves any particular purpose or works at all,
15*41197Sbostic unless he says so in writing. Refer to the CHESS General Public
16*41197Sbostic License for full details.
17*41197Sbostic
18*41197Sbostic Everyone is granted permission to copy, modify and redistribute
19*41197Sbostic CHESS, but only under the conditions described in the
20*41197Sbostic CHESS General Public License. A copy of this license is
21*41197Sbostic supposed to have been given to you along with CHESS so you
22*41197Sbostic can know your rights and responsibilities. It should be in a
23*41197Sbostic file named COPYING. Among other things, the copyright notice
24*41197Sbostic and this notice must be preserved on all copies.
25*41197Sbostic */
26*41197Sbostic
27*41197Sbostic
28*41197Sbostic #include <stdio.h>
29*41197Sbostic #include <ctype.h>
30*41197Sbostic #ifdef MSDOS
31*41197Sbostic #include <dos.h>
32*41197Sbostic #include <stdlib.h>
33*41197Sbostic #include <time.h>
34*41197Sbostic #else
35*41197Sbostic #include <sys/param.h>
36*41197Sbostic #include <sys/times.h>
37*41197Sbostic #include <sys/file.h>
38*41197Sbostic struct tms tmbuf1,tmbuf2;
39*41197Sbostic int TerminateSearch(),Die();
40*41197Sbostic #endif MSDOS
41*41197Sbostic
42*41197Sbostic #include "gnuchess.h"
43*41197Sbostic #ifdef NEWMOVE
44*41197Sbostic #include "move.h"
45*41197Sbostic #endif
46*41197Sbostic
47*41197Sbostic #define printz printf
48*41197Sbostic #define scanz scanf
49*41197Sbostic int mycnt1,mycnt2;
50*41197Sbostic
51*41197Sbostic
Initialize()52*41197Sbostic Initialize()
53*41197Sbostic {
54*41197Sbostic mycnt1 = mycnt2 = 0;
55*41197Sbostic #ifndef MSDOS
56*41197Sbostic #endif
57*41197Sbostic #ifdef CHESSTOOL
58*41197Sbostic setlinebuf(stdout);
59*41197Sbostic /*
60*41197Sbostic setvbuf(stdout,NULL,_IOLBF,BUFSIZ);
61*41197Sbostic */
62*41197Sbostic printf("Chess\n");
63*41197Sbostic if (Level == 0 && !TCflag) Level = 15;
64*41197Sbostic #endif CHESSTOOL
65*41197Sbostic }
66*41197Sbostic
ExitChess()67*41197Sbostic ExitChess()
68*41197Sbostic {
69*41197Sbostic ListGame();
70*41197Sbostic exit(0);
71*41197Sbostic }
72*41197Sbostic
73*41197Sbostic #ifndef MSDOS
Die()74*41197Sbostic Die()
75*41197Sbostic {
76*41197Sbostic char s[80];
77*41197Sbostic printz("Abort? ");
78*41197Sbostic scanz("%s",s);
79*41197Sbostic if (strcmp(s,"yes") == 0) ExitChess();
80*41197Sbostic }
81*41197Sbostic
TerminateSearch()82*41197Sbostic TerminateSearch()
83*41197Sbostic {
84*41197Sbostic timeout = true;
85*41197Sbostic bothsides = false;
86*41197Sbostic }
87*41197Sbostic #endif MSDOS
88*41197Sbostic
89*41197Sbostic
InputCommand()90*41197Sbostic InputCommand()
91*41197Sbostic
92*41197Sbostic /*
93*41197Sbostic Process the users command. If easy mode is OFF (the computer is
94*41197Sbostic thinking on opponents time) and the program is out of book, then make
95*41197Sbostic the 'hint' move on the board and call SelectMove() to find a response.
96*41197Sbostic The user terminates the search by entering ^C (quit siqnal) before
97*41197Sbostic entering a command. If the opponent does not make the hint move, then
98*41197Sbostic set Sdepth to zero.
99*41197Sbostic */
100*41197Sbostic
101*41197Sbostic {
102*41197Sbostic int i;
103*41197Sbostic short ok,tmp;
104*41197Sbostic long cnt,rate,t1,t2;
105*41197Sbostic unsigned short mv;
106*41197Sbostic char s[80];
107*41197Sbostic
108*41197Sbostic ok = quit = false;
109*41197Sbostic player = opponent;
110*41197Sbostic ft = 0;
111*41197Sbostic if (hint > 0 && !easy && Book == NULL)
112*41197Sbostic {
113*41197Sbostic fflush(stdout);
114*41197Sbostic time0 = time((long *)0);
115*41197Sbostic algbr(hint>>8,hint & 0xFF,false);
116*41197Sbostic strcpy(s,mvstr1);
117*41197Sbostic tmp = epsquare;
118*41197Sbostic if (VerifyMove(s,1,&mv))
119*41197Sbostic {
120*41197Sbostic SelectMove(computer,2);
121*41197Sbostic VerifyMove(mvstr1,2,&mv);
122*41197Sbostic if (Sdepth > 0) Sdepth--;
123*41197Sbostic }
124*41197Sbostic ft = time((long *)0) - time0;
125*41197Sbostic epsquare = tmp;
126*41197Sbostic }
127*41197Sbostic
128*41197Sbostic #ifndef MSDOS
129*41197Sbostic #endif
130*41197Sbostic while (!(ok || quit))
131*41197Sbostic {
132*41197Sbostic PromptForMove();
133*41197Sbostic i = scanz("%s",s);
134*41197Sbostic if (i == EOF || s[0] == 0) ExitChess();
135*41197Sbostic player = opponent;
136*41197Sbostic ok = VerifyMove(s,0,&mv);
137*41197Sbostic if (ok && mv != hint)
138*41197Sbostic {
139*41197Sbostic Sdepth = 0;
140*41197Sbostic ft = 0;
141*41197Sbostic }
142*41197Sbostic
143*41197Sbostic if (strcmp(s,"bd") == 0)
144*41197Sbostic {
145*41197Sbostic ClrScreen();
146*41197Sbostic UpdateDisplay(0,0,1,0);
147*41197Sbostic }
148*41197Sbostic if (strcmp(s,"quit") == 0) quit = true;
149*41197Sbostic if (strcmp(s,"post") == 0) post = !post;
150*41197Sbostic if (strcmp(s,"set") == 0) EditBoard();
151*41197Sbostic if (strcmp(s,"go") == 0) ok = true;
152*41197Sbostic if (strcmp(s,"help") == 0) help();
153*41197Sbostic if (strcmp(s,"force") == 0) force = !force;
154*41197Sbostic if (strcmp(s,"book") == 0) Book = NULL;
155*41197Sbostic if (strcmp(s,"new") == 0) NewGame();
156*41197Sbostic if (strcmp(s,"list") == 0) ListGame();
157*41197Sbostic if (strcmp(s,"level") == 0) SelectLevel();
158*41197Sbostic if (strcmp(s,"hash") == 0) hashflag = !hashflag;
159*41197Sbostic if (strcmp(s,"beep") == 0) beep = !beep;
160*41197Sbostic if (strcmp(s,"Awindow") == 0) ChangeAlphaWindow();
161*41197Sbostic if (strcmp(s,"Bwindow") == 0) ChangeBetaWindow();
162*41197Sbostic if (strcmp(s,"rcptr") == 0) rcptr = !rcptr;
163*41197Sbostic if (strcmp(s,"hint") == 0) GiveHint();
164*41197Sbostic if (strcmp(s,"zero") == 0) ZeroTTable();
165*41197Sbostic if (strcmp(s,"both") == 0)
166*41197Sbostic {
167*41197Sbostic bothsides = !bothsides;
168*41197Sbostic Sdepth = 0;
169*41197Sbostic SelectMove(opponent,1);
170*41197Sbostic ok = true;
171*41197Sbostic }
172*41197Sbostic if (strcmp(s,"reverse") == 0)
173*41197Sbostic {
174*41197Sbostic reverse = !reverse;
175*41197Sbostic ClrScreen();
176*41197Sbostic UpdateDisplay(0,0,1,0);
177*41197Sbostic }
178*41197Sbostic if (strcmp(s,"switch") == 0)
179*41197Sbostic {
180*41197Sbostic computer = otherside[computer];
181*41197Sbostic opponent = otherside[opponent];
182*41197Sbostic force = false;
183*41197Sbostic Sdepth = 0;
184*41197Sbostic ok = true;
185*41197Sbostic }
186*41197Sbostic if (strcmp(s,"white") == 0)
187*41197Sbostic {
188*41197Sbostic computer = white; opponent = black;
189*41197Sbostic ok = true; force = false;
190*41197Sbostic Sdepth = 0;
191*41197Sbostic }
192*41197Sbostic if (strcmp(s,"black") == 0)
193*41197Sbostic {
194*41197Sbostic computer = black; opponent = white;
195*41197Sbostic ok = true; force = false;
196*41197Sbostic Sdepth = 0;
197*41197Sbostic }
198*41197Sbostic if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo();
199*41197Sbostic if (strcmp(s,"remove") == 0 && GameCnt >= 1)
200*41197Sbostic {
201*41197Sbostic Undo(); Undo();
202*41197Sbostic }
203*41197Sbostic if (strcmp(s,"get") == 0) GetGame();
204*41197Sbostic if (strcmp(s,"save") == 0) SaveGame();
205*41197Sbostic if (strcmp(s,"depth") == 0) ChangeSearchDepth();
206*41197Sbostic if (strcmp(s,"random") == 0) dither = 6;
207*41197Sbostic if (strcmp(s,"easy") == 0) easy = !easy;
208*41197Sbostic if (strcmp(s,"contempt") == 0) SetContempt();
209*41197Sbostic if (strcmp(s,"xwndw") == 0) ChangeXwindow();
210*41197Sbostic if (strcmp(s,"test") == 0)
211*41197Sbostic {
212*41197Sbostic t1 = time(0);
213*41197Sbostic cnt = 0;
214*41197Sbostic for (i = 0; i < 10000; i++)
215*41197Sbostic {
216*41197Sbostic MoveList(opponent,2);
217*41197Sbostic cnt += TrPnt[3] - TrPnt[2];
218*41197Sbostic }
219*41197Sbostic t2 = time(0);
220*41197Sbostic rate = cnt / (t2-t1);
221*41197Sbostic printz("cnt= %ld rate= %ld\n",cnt,rate);
222*41197Sbostic }
223*41197Sbostic }
224*41197Sbostic
225*41197Sbostic ElapsedTime(1);
226*41197Sbostic if (force)
227*41197Sbostic {
228*41197Sbostic computer = opponent; opponent = otherside[computer];
229*41197Sbostic }
230*41197Sbostic #ifndef MSDOS
231*41197Sbostic (void) times(&tmbuf1);
232*41197Sbostic #ifdef CHESSTOOL
233*41197Sbostic printf("%d. %s\n",++mycnt2,s);
234*41197Sbostic #endif CHESSTOOL
235*41197Sbostic #endif MSDOS
236*41197Sbostic }
237*41197Sbostic
238*41197Sbostic
help()239*41197Sbostic help()
240*41197Sbostic {
241*41197Sbostic ClrScreen();
242*41197Sbostic printz("CHESS command summary\n");
243*41197Sbostic printz("g1f3 move from g1 to f3\n");
244*41197Sbostic printz("nf3 move knight to f3\n");
245*41197Sbostic printz("o-o castle king side\n");
246*41197Sbostic printz("o-o-o castle queen side\n");
247*41197Sbostic printz("set edit board\n");
248*41197Sbostic printz("switch sides with computer\n");
249*41197Sbostic printz("white computer plays white\n");
250*41197Sbostic printz("black computer plays black\n");
251*41197Sbostic printz("reverse board display\n");
252*41197Sbostic printz("both computer match\n");
253*41197Sbostic printz("random randomize play\n");
254*41197Sbostic printz("undo undo last move\n");
255*41197Sbostic printz("time change level\n");
256*41197Sbostic printz("depth set search depth\n");
257*41197Sbostic printz("post principle variation\n");
258*41197Sbostic printz("hint suggest a move\n");
259*41197Sbostic printz("bd redraw board\n");
260*41197Sbostic printz("clock set time control\n");
261*41197Sbostic printz("force enter game moves\n");
262*41197Sbostic printz("list game to chess.lst\n");
263*41197Sbostic printz("save game to file\n");
264*41197Sbostic printz("get game from file\n");
265*41197Sbostic printz("new start new game\n");
266*41197Sbostic printz("quit exit CHESS\n");
267*41197Sbostic printz("Computer: ");
268*41197Sbostic if (computer == white) printz("WHITE\n"); else printz("BLACK\n");
269*41197Sbostic printz("Opponent: ");
270*41197Sbostic if (opponent == white) printz("WHITE\n"); else printz("BLACK\n");
271*41197Sbostic printz("Response time: %ld",Level," sec.\n");
272*41197Sbostic printz("Easy mode: ");
273*41197Sbostic if (easy) printz("ON\n"); else printz("OFF\n");
274*41197Sbostic printz("Depth: %d\n",MaxSearchDepth);
275*41197Sbostic printz("Random: ");
276*41197Sbostic if (dither) printz("ON\n"); else printz("OFF\n");
277*41197Sbostic printz("Transposition table: ");
278*41197Sbostic if (hashflag) printz("ON\n"); else printz("OFF\n");
279*41197Sbostic UpdateDisplay(0,0,1,0);
280*41197Sbostic }
281*41197Sbostic
282*41197Sbostic
EditBoard()283*41197Sbostic EditBoard()
284*41197Sbostic
285*41197Sbostic /*
286*41197Sbostic Set up a board position. Pieces are entered by typing the piece
287*41197Sbostic followed by the location. For example, Nf3 will place a knight on
288*41197Sbostic square f3.
289*41197Sbostic */
290*41197Sbostic
291*41197Sbostic {
292*41197Sbostic short a,r,c,sq;
293*41197Sbostic char s[80];
294*41197Sbostic
295*41197Sbostic ClrScreen();
296*41197Sbostic UpdateDisplay(0,0,1,0);
297*41197Sbostic printz(". exit to main\n");
298*41197Sbostic printz("# clear board\n");
299*41197Sbostic printz("enter piece & location: \n");
300*41197Sbostic
301*41197Sbostic a = white;
302*41197Sbostic do
303*41197Sbostic {
304*41197Sbostic scanz("%s",s);
305*41197Sbostic if (s[0] == '#')
306*41197Sbostic {
307*41197Sbostic for (sq = 0; sq < 64; sq++)
308*41197Sbostic {
309*41197Sbostic board[sq] = no_piece; color[sq] = neutral;
310*41197Sbostic }
311*41197Sbostic UpdateDisplay(0,0,1,0);
312*41197Sbostic }
313*41197Sbostic if (s[0] == 'c' || s[0] == 'C') a = otherside[a];
314*41197Sbostic c = s[1]-'a'; r = s[2]-'1';
315*41197Sbostic if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
316*41197Sbostic {
317*41197Sbostic sq = locn[r][c];
318*41197Sbostic color[sq] = a;
319*41197Sbostic if (s[0] == 'p') board[sq] = pawn;
320*41197Sbostic else if (s[0] == 'n') board[sq] = knight;
321*41197Sbostic else if (s[0] == 'b') board[sq] = bishop;
322*41197Sbostic else if (s[0] == 'r') board[sq] = rook;
323*41197Sbostic else if (s[0] == 'q') board[sq] = queen;
324*41197Sbostic else if (s[0] == 'k') board[sq] = king;
325*41197Sbostic else { board[sq] = no_piece; color[sq] = neutral; }
326*41197Sbostic }
327*41197Sbostic }
328*41197Sbostic while (s[0] != '.');
329*41197Sbostic if (board[4] != king) kingmoved[white] = 10;
330*41197Sbostic if (board[60] != king) kingmoved[black] = 10;
331*41197Sbostic GameCnt = -1; Game50 = 0; Sdepth = 0;
332*41197Sbostic InitializeStats();
333*41197Sbostic ClrScreen();
334*41197Sbostic UpdateDisplay(0,0,1,0);
335*41197Sbostic }
336*41197Sbostic
337*41197Sbostic
ShowDepth(ch)338*41197Sbostic ShowDepth(ch)
339*41197Sbostic char ch;
340*41197Sbostic {
341*41197Sbostic }
342*41197Sbostic
ShowResults(score,bstline,ch)343*41197Sbostic ShowResults(score,bstline,ch)
344*41197Sbostic short score;
345*41197Sbostic unsigned short bstline[];
346*41197Sbostic char ch;
347*41197Sbostic {
348*41197Sbostic #ifndef CHESSTOOL
349*41197Sbostic register int i;
350*41197Sbostic printz("%2d%c %5d %4ld %7ld ",Sdepth,ch,score,et,NodeCnt);
351*41197Sbostic for (i = 1; bstline[i] > 0; i++)
352*41197Sbostic {
353*41197Sbostic algbr((short)(bstline[i] >> 8),(short)(bstline[i] & 0xFF),false);
354*41197Sbostic if (i == 9 || i == 17) printz("\n ");
355*41197Sbostic printz("%5s ",mvstr1);
356*41197Sbostic }
357*41197Sbostic printz("\n");
358*41197Sbostic #endif
359*41197Sbostic }
360*41197Sbostic
361*41197Sbostic
SearchStartStuff(side)362*41197Sbostic SearchStartStuff(side)
363*41197Sbostic short side;
364*41197Sbostic {
365*41197Sbostic #ifndef MSDOS
366*41197Sbostic #endif
367*41197Sbostic #ifndef CHESSTOOL
368*41197Sbostic printz("\nMove# %d Target= %ld Clock: %ld\n",
369*41197Sbostic TCmoves-TimeControl.moves[side]+1,
370*41197Sbostic ResponseTime,TimeControl.clock[side]);
371*41197Sbostic #endif
372*41197Sbostic }
373*41197Sbostic
374*41197Sbostic
OutputMove()375*41197Sbostic OutputMove()
376*41197Sbostic {
377*41197Sbostic #ifdef CHESSTOOL
378*41197Sbostic printz("%d. ... %s\n",++mycnt1,mvstr1);
379*41197Sbostic if (root->flags & draw)
380*41197Sbostic {
381*41197Sbostic printz("Draw\n");
382*41197Sbostic ListGame();
383*41197Sbostic exit(0);
384*41197Sbostic }
385*41197Sbostic if (root->score == -9999)
386*41197Sbostic {
387*41197Sbostic if (opponent == white) printz("White\n"); else printz("Black\n");
388*41197Sbostic ListGame();
389*41197Sbostic exit(0);
390*41197Sbostic }
391*41197Sbostic if (root->score == 9998)
392*41197Sbostic {
393*41197Sbostic if (computer == white) printz("White\n"); else printz("Black\n");
394*41197Sbostic ListGame();
395*41197Sbostic exit(0);
396*41197Sbostic }
397*41197Sbostic #else
398*41197Sbostic printz("Nodes= %ld Eval= %ld Hash= %ld Rate= %ld ",
399*41197Sbostic NodeCnt,EvalNodes,HashCnt,evrate);
400*41197Sbostic printz("CPU= %.2ld:%.2ld.%.2ld\n\n",
401*41197Sbostic cputimer/6000,(cputimer % 6000)/100,cputimer % 100);
402*41197Sbostic
403*41197Sbostic if (root->flags & epmask) UpdateDisplay(0,0,1,0);
404*41197Sbostic else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask);
405*41197Sbostic printz("My move is: %s\n\n",mvstr1);
406*41197Sbostic if (beep) printz("%c",7);
407*41197Sbostic
408*41197Sbostic if (root->flags & draw) printz("Draw game!\n");
409*41197Sbostic else if (root->score == -9999) printz("opponent mates!\n");
410*41197Sbostic else if (root->score == 9998) printz("computer mates!\n");
411*41197Sbostic else if (root->score < -9000) printz("opponent will soon mate!\n");
412*41197Sbostic else if (root->score > 9000) printz("computer will soon mate!\n");
413*41197Sbostic #endif CHESSTOOL
414*41197Sbostic }
415*41197Sbostic
416*41197Sbostic
ElapsedTime(iop)417*41197Sbostic ElapsedTime(iop)
418*41197Sbostic short iop;
419*41197Sbostic
420*41197Sbostic /*
421*41197Sbostic Determine the time that has passed since the search was started. If
422*41197Sbostic the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
423*41197Sbostic timeout to true which will terminate the search.
424*41197Sbostic */
425*41197Sbostic
426*41197Sbostic {
427*41197Sbostic et = time((long *)0) - time0;
428*41197Sbostic if (et < 0) et = 0;
429*41197Sbostic ETnodes += 50;
430*41197Sbostic if (et > et0 || iop == 1)
431*41197Sbostic {
432*41197Sbostic if (et > ResponseTime+ExtraTime && Sdepth > 1) timeout = true;
433*41197Sbostic et0 = et;
434*41197Sbostic if (iop == 1)
435*41197Sbostic {
436*41197Sbostic time0 = time((long *)0); et0 = 0;
437*41197Sbostic }
438*41197Sbostic #ifdef MSDOS
439*41197Sbostic cputimer = 100*et;
440*41197Sbostic if (et > 0) evrate = NodeCnt/(et+ft); else evrate = 0;
441*41197Sbostic if (kbhit() && Sdepth > 1)
442*41197Sbostic {
443*41197Sbostic timeout = true;
444*41197Sbostic bothsides = false;
445*41197Sbostic }
446*41197Sbostic #else
447*41197Sbostic (void) times(&tmbuf2);
448*41197Sbostic cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ;
449*41197Sbostic if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft);
450*41197Sbostic else evrate = 0;
451*41197Sbostic #endif MSDOS
452*41197Sbostic ETnodes = NodeCnt + 50;
453*41197Sbostic }
454*41197Sbostic }
455*41197Sbostic
456*41197Sbostic
SetTimeControl()457*41197Sbostic SetTimeControl()
458*41197Sbostic {
459*41197Sbostic if (TCflag)
460*41197Sbostic {
461*41197Sbostic TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
462*41197Sbostic TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes;
463*41197Sbostic }
464*41197Sbostic else
465*41197Sbostic {
466*41197Sbostic TimeControl.moves[white] = TimeControl.moves[black] = 0;
467*41197Sbostic TimeControl.clock[white] = TimeControl.clock[black] = 0;
468*41197Sbostic Level = 60*(long)TCminutes;
469*41197Sbostic }
470*41197Sbostic et = 0;
471*41197Sbostic ElapsedTime(1);
472*41197Sbostic }
473*41197Sbostic
474*41197Sbostic
ClrScreen()475*41197Sbostic ClrScreen()
476*41197Sbostic {
477*41197Sbostic #ifndef CHESSTOOL
478*41197Sbostic printz("\n");
479*41197Sbostic #endif
480*41197Sbostic }
481*41197Sbostic
482*41197Sbostic
UpdateDisplay(f,t,flag,iscastle)483*41197Sbostic UpdateDisplay(f,t,flag,iscastle)
484*41197Sbostic short f,t,flag,iscastle;
485*41197Sbostic {
486*41197Sbostic #ifndef CHESSTOOL
487*41197Sbostic short r,c,l;
488*41197Sbostic if (flag)
489*41197Sbostic {
490*41197Sbostic printz("\n");
491*41197Sbostic for (r = 7; r >= 0; r--)
492*41197Sbostic {
493*41197Sbostic for (c = 0; c <= 7; c++)
494*41197Sbostic {
495*41197Sbostic if (reverse) l = locn[7-r][7-c]; else l = locn[r][c];
496*41197Sbostic if (color[l] == neutral) printz(" -");
497*41197Sbostic else if (color[l] == white) printz(" %c",qxx[board[l]]);
498*41197Sbostic else printz(" %c",pxx[board[l]]);
499*41197Sbostic }
500*41197Sbostic printz("\n");
501*41197Sbostic }
502*41197Sbostic printz("\n");
503*41197Sbostic }
504*41197Sbostic #endif CHESSTOOL
505*41197Sbostic }
506*41197Sbostic
507*41197Sbostic
GetOpenings()508*41197Sbostic GetOpenings()
509*41197Sbostic
510*41197Sbostic /*
511*41197Sbostic Read in the Opening Book file and parse the algebraic notation for a
512*41197Sbostic move into an unsigned integer format indicating the from and to
513*41197Sbostic square. Create a linked list of opening lines of play, with
514*41197Sbostic entry->next pointing to the next line and entry->move pointing to a
515*41197Sbostic chunk of memory containing the moves. More Opening lines of up to 256
516*41197Sbostic half moves may be added to gnuchess.book.
517*41197Sbostic */
518*41197Sbostic
519*41197Sbostic {
520*41197Sbostic FILE *fd;
521*41197Sbostic int c,i,j,side;
522*41197Sbostic char buffr[2048];
523*41197Sbostic struct BookEntry *entry;
524*41197Sbostic unsigned short mv,*mp,tmp[100];
525*41197Sbostic
526*41197Sbostic if ((fd = fopen("gnuchess.book","r")) != NULL)
527*41197Sbostic {
528*41197Sbostic /*
529*41197Sbostic setvbuf(fd,buffr,_IOFBF,2048);
530*41197Sbostic */
531*41197Sbostic Book = NULL;
532*41197Sbostic i = 0; side = white;
533*41197Sbostic while ((c = parse(fd,&mv,side)) >= 0)
534*41197Sbostic if (c == 1)
535*41197Sbostic {
536*41197Sbostic tmp[++i] = mv;
537*41197Sbostic side = otherside[side];
538*41197Sbostic }
539*41197Sbostic else if (c == 0 && i > 0)
540*41197Sbostic {
541*41197Sbostic entry = (struct BookEntry *)malloc(sizeof(struct BookEntry));
542*41197Sbostic mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short));
543*41197Sbostic entry->mv = mp;
544*41197Sbostic entry->next = Book;
545*41197Sbostic Book = entry;
546*41197Sbostic for (j = 1; j <= i; j++) *(mp++) = tmp[j];
547*41197Sbostic *mp = 0;
548*41197Sbostic i = 0; side = white;
549*41197Sbostic }
550*41197Sbostic fclose(fd);
551*41197Sbostic }
552*41197Sbostic }
553*41197Sbostic
554*41197Sbostic
parse(fd,mv,side)555*41197Sbostic int parse(fd,mv,side)
556*41197Sbostic FILE *fd;
557*41197Sbostic unsigned short *mv;
558*41197Sbostic short side;
559*41197Sbostic {
560*41197Sbostic int c,i,r1,r2,c1,c2;
561*41197Sbostic char s[100];
562*41197Sbostic while ((c = getc(fd)) == ' ');
563*41197Sbostic i = 0; s[0] = c;
564*41197Sbostic while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd);
565*41197Sbostic s[++i] = '\0';
566*41197Sbostic if (c == EOF) return(-1);
567*41197Sbostic if (s[0] == '!' || i < 3)
568*41197Sbostic {
569*41197Sbostic while (c != '\n' && c != EOF) c = getc(fd);
570*41197Sbostic return(0);
571*41197Sbostic }
572*41197Sbostic if (s[4] == 'o')
573*41197Sbostic if (side == black) *mv = 0x3C3A; else *mv = 0x0402;
574*41197Sbostic else if (s[0] == 'o')
575*41197Sbostic if (side == black) *mv = 0x3C3E; else *mv = 0x0406;
576*41197Sbostic else
577*41197Sbostic {
578*41197Sbostic c1 = s[0] - 'a'; r1 = s[1] - '1';
579*41197Sbostic c2 = s[2] - 'a'; r2 = s[3] - '1';
580*41197Sbostic *mv = (locn[r1][c1]<<8) + locn[r2][c2];
581*41197Sbostic }
582*41197Sbostic return(1);
583*41197Sbostic }
584*41197Sbostic
585*41197Sbostic
GetGame()586*41197Sbostic GetGame()
587*41197Sbostic {
588*41197Sbostic FILE *fd;
589*41197Sbostic char fname[40];
590*41197Sbostic int c;
591*41197Sbostic short sq;
592*41197Sbostic unsigned short m;
593*41197Sbostic
594*41197Sbostic printz("Enter file name: ");
595*41197Sbostic scanz("%s",fname);
596*41197Sbostic if (fname[0] == '\0') strcpy(fname,"chess.000");
597*41197Sbostic if ((fd = fopen(fname,"r")) != NULL)
598*41197Sbostic {
599*41197Sbostic fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
600*41197Sbostic fscanf(fd,"%hd%hd%hd%hd",
601*41197Sbostic &castld[white],&castld[black],
602*41197Sbostic &kingmoved[white],&kingmoved[black]);
603*41197Sbostic fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
604*41197Sbostic fscanf(fd,"%ld%ld%hd%hd",
605*41197Sbostic &TimeControl.clock[white],&TimeControl.clock[black],
606*41197Sbostic &TimeControl.moves[white],&TimeControl.moves[black]);
607*41197Sbostic for (sq = 0; sq < 64; sq++)
608*41197Sbostic {
609*41197Sbostic fscanf(fd,"%hd",&m);
610*41197Sbostic board[sq] = (m >> 8); color[sq] = (m & 0xFF);
611*41197Sbostic if (color[sq] == 0) color[sq] = neutral; else --color[sq];
612*41197Sbostic }
613*41197Sbostic GameCnt = -1; c = '?';
614*41197Sbostic while (c != EOF)
615*41197Sbostic {
616*41197Sbostic ++GameCnt;
617*41197Sbostic c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
618*41197Sbostic &GameList[GameCnt].score,&GameList[GameCnt].depth,
619*41197Sbostic &GameList[GameCnt].nodes,&GameList[GameCnt].time,
620*41197Sbostic &GameList[GameCnt].piece,&GameList[GameCnt].color);
621*41197Sbostic if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral;
622*41197Sbostic else --GameList[GameCnt].color;
623*41197Sbostic }
624*41197Sbostic GameCnt--;
625*41197Sbostic if (TimeControl.clock[white] > 0) TCflag = true;
626*41197Sbostic computer--; opponent--;
627*41197Sbostic }
628*41197Sbostic fclose(fd);
629*41197Sbostic InitializeStats();
630*41197Sbostic UpdateDisplay(0,0,1,0);
631*41197Sbostic Sdepth = 0;
632*41197Sbostic }
633*41197Sbostic
634*41197Sbostic
SaveGame()635*41197Sbostic SaveGame()
636*41197Sbostic {
637*41197Sbostic FILE *fd;
638*41197Sbostic char fname[40];
639*41197Sbostic short sq,i,c;
640*41197Sbostic
641*41197Sbostic printz("Enter file name: ");
642*41197Sbostic scanz("%s",fname);
643*41197Sbostic
644*41197Sbostic if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000");
645*41197Sbostic fd = fopen(fname,"w");
646*41197Sbostic fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50);
647*41197Sbostic fprintf(fd,"%d %d %d %d\n",
648*41197Sbostic castld[white],castld[black],kingmoved[white],kingmoved[black]);
649*41197Sbostic fprintf(fd,"%d %d\n",TCflag,OperatorTime);
650*41197Sbostic fprintf(fd,"%ld %ld %d %d\n",
651*41197Sbostic TimeControl.clock[white],TimeControl.clock[black],
652*41197Sbostic TimeControl.moves[white],TimeControl.moves[black]);
653*41197Sbostic for (sq = 0; sq < 64; sq++)
654*41197Sbostic {
655*41197Sbostic if (color[sq] == neutral) c = 0; else c = color[sq]+1;
656*41197Sbostic fprintf(fd,"%d\n",256*board[sq] + c);
657*41197Sbostic }
658*41197Sbostic for (i = 0; i <= GameCnt; i++)
659*41197Sbostic {
660*41197Sbostic if (GameList[i].color == neutral) c = 0;
661*41197Sbostic else c = GameList[i].color + 1;
662*41197Sbostic fprintf(fd,"%d %d %d %ld %d %d %d\n",
663*41197Sbostic GameList[i].gmove,GameList[i].score,GameList[i].depth,
664*41197Sbostic GameList[i].nodes,GameList[i].time,
665*41197Sbostic GameList[i].piece,c);
666*41197Sbostic }
667*41197Sbostic fclose(fd);
668*41197Sbostic }
669*41197Sbostic
670*41197Sbostic
ListGame()671*41197Sbostic ListGame()
672*41197Sbostic {
673*41197Sbostic FILE *fd;
674*41197Sbostic short i,f,t;
675*41197Sbostic fd = fopen("chess.lst","w");
676*41197Sbostic fprintf(fd,"\n");
677*41197Sbostic fprintf(fd," score depth nodes time ");
678*41197Sbostic fprintf(fd," score depth nodes time\n");
679*41197Sbostic for (i = 0; i <= GameCnt; i++)
680*41197Sbostic {
681*41197Sbostic f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
682*41197Sbostic algbr(f,t,false);
683*41197Sbostic if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," ");
684*41197Sbostic fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1,
685*41197Sbostic GameList[i].score,GameList[i].depth,
686*41197Sbostic GameList[i].nodes,GameList[i].time);
687*41197Sbostic }
688*41197Sbostic fprintf(fd,"\n\n");
689*41197Sbostic fclose(fd);
690*41197Sbostic }
691*41197Sbostic
692*41197Sbostic
Undo()693*41197Sbostic Undo()
694*41197Sbostic
695*41197Sbostic /*
696*41197Sbostic Undo the most recent half-move.
697*41197Sbostic */
698*41197Sbostic
699*41197Sbostic {
700*41197Sbostic short f,t;
701*41197Sbostic f = GameList[GameCnt].gmove>>8;
702*41197Sbostic t = GameList[GameCnt].gmove & 0xFF;
703*41197Sbostic if (board[t] == king && distance(t,f) > 1)
704*41197Sbostic castle(GameList[GameCnt].color,f,t,2);
705*41197Sbostic else
706*41197Sbostic {
707*41197Sbostic board[f] = board[t]; color[f] = color[t];
708*41197Sbostic board[t] = GameList[GameCnt].piece;
709*41197Sbostic color[t] = GameList[GameCnt].color;
710*41197Sbostic if (board[f] == king) --kingmoved[color[f]];
711*41197Sbostic }
712*41197Sbostic if (TCflag) ++TimeControl.moves[color[f]];
713*41197Sbostic GameCnt--; mate = false; Sdepth = 0;
714*41197Sbostic UpdateDisplay(0,0,1,0);
715*41197Sbostic InitializeStats();
716*41197Sbostic }
717*41197Sbostic
718*41197Sbostic
ShowMessage(s)719*41197Sbostic ShowMessage(s)
720*41197Sbostic char *s;
721*41197Sbostic {
722*41197Sbostic #ifndef CHESSTOOL
723*41197Sbostic printz("%s\n");
724*41197Sbostic #endif CHESSTOOL
725*41197Sbostic }
726*41197Sbostic
ShowSidetomove()727*41197Sbostic ShowSidetomove()
728*41197Sbostic {
729*41197Sbostic }
730*41197Sbostic
PromptForMove()731*41197Sbostic PromptForMove()
732*41197Sbostic {
733*41197Sbostic #ifndef CHESSTOOL
734*41197Sbostic printz("\nYour move is? ");
735*41197Sbostic #endif CHESSTOOL
736*41197Sbostic }
737*41197Sbostic
738*41197Sbostic
ShowCurrentMove(pnt,f,t)739*41197Sbostic ShowCurrentMove(pnt,f,t)
740*41197Sbostic short pnt,f,t;
741*41197Sbostic {
742*41197Sbostic }
743*41197Sbostic
ChangeAlphaWindow()744*41197Sbostic ChangeAlphaWindow()
745*41197Sbostic {
746*41197Sbostic printz("window: ");
747*41197Sbostic scanz("%hd",&Awindow);
748*41197Sbostic }
749*41197Sbostic
ChangeBetaWindow()750*41197Sbostic ChangeBetaWindow()
751*41197Sbostic {
752*41197Sbostic printz("window: ");
753*41197Sbostic scanz("%hd",&Bwindow);
754*41197Sbostic }
755*41197Sbostic
GiveHint()756*41197Sbostic GiveHint()
757*41197Sbostic {
758*41197Sbostic algbr((short)(hint>>8),(short)(hint & 0xFF),false);
759*41197Sbostic printz("try %s\n",mvstr1);
760*41197Sbostic }
761*41197Sbostic
762*41197Sbostic
SelectLevel()763*41197Sbostic SelectLevel()
764*41197Sbostic {
765*41197Sbostic OperatorTime = 30000;
766*41197Sbostic printz("Enter #moves #minutes: ");
767*41197Sbostic scanz("%hd %hd",&TCmoves,&TCminutes);
768*41197Sbostic printz("Operator time= ");
769*41197Sbostic scanz("%hd",&OperatorTime);
770*41197Sbostic TCflag = (TCmoves > 1);
771*41197Sbostic SetTimeControl();
772*41197Sbostic }
773*41197Sbostic
774*41197Sbostic
ChangeSearchDepth()775*41197Sbostic ChangeSearchDepth()
776*41197Sbostic {
777*41197Sbostic printz("depth= ");
778*41197Sbostic scanz("%hd",&MaxSearchDepth);
779*41197Sbostic }
780*41197Sbostic
SetContempt()781*41197Sbostic SetContempt()
782*41197Sbostic {
783*41197Sbostic printz("contempt= ");
784*41197Sbostic scanz("%hd",&contempt);
785*41197Sbostic }
786*41197Sbostic
ChangeXwindow()787*41197Sbostic ChangeXwindow()
788*41197Sbostic {
789*41197Sbostic printz("xwndw= ");
790*41197Sbostic scanz("%hd",&xwndw);
791*41197Sbostic }
792