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