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