|
|
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.