141198Sbostic /* 241198Sbostic ALPHA interface for CHESS 341198Sbostic 441198Sbostic Revision: 4-25-88 541198Sbostic 641198Sbostic Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. 741198Sbostic Copyright (c) 1988 John Stanback 841198Sbostic 941198Sbostic This file is part of CHESS. 1041198Sbostic 1141198Sbostic CHESS is distributed in the hope that it will be useful, 1241198Sbostic but WITHOUT ANY WARRANTY. No author or distributor 1341198Sbostic accepts responsibility to anyone for the consequences of using it 1441198Sbostic or for whether it serves any particular purpose or works at all, 1541198Sbostic unless he says so in writing. Refer to the CHESS General Public 1641198Sbostic License for full details. 1741198Sbostic 1841198Sbostic Everyone is granted permission to copy, modify and redistribute 1941198Sbostic CHESS, but only under the conditions described in the 2041198Sbostic CHESS General Public License. A copy of this license is 2141198Sbostic supposed to have been given to you along with CHESS so you 2241198Sbostic can know your rights and responsibilities. It should be in a 2341198Sbostic file named COPYING. Among other things, the copyright notice 2441198Sbostic and this notice must be preserved on all copies. 2541198Sbostic */ 2641198Sbostic 2741198Sbostic 2841198Sbostic #include <stdio.h> 2941198Sbostic #include <ctype.h> 3041198Sbostic #include <sys/param.h> 3141198Sbostic #include <sys/times.h> 3241198Sbostic #include <sys/file.h> 3341198Sbostic #include <curses.h> 3441198Sbostic #include <signal.h> 3541198Sbostic #include "gnuchess.h" 3641198Sbostic #ifdef NEWMOVE 3741198Sbostic #include "move.h" 3841198Sbostic #endif 3941199Sbostic #include "pathnames.h" 4041198Sbostic 4141198Sbostic struct tms tmbuf1,tmbuf2; 42*46740Sbostic void TerminateSearch(),Die(); 4341198Sbostic 4441198Sbostic #define scanz fflush(stdout),scanw 4541198Sbostic #define printz printw 4641198Sbostic 4741198Sbostic 4841198Sbostic Initialize() 4941198Sbostic { 5041198Sbostic signal(SIGINT,Die); signal(SIGQUIT,Die); 5141198Sbostic initscr(); 5241198Sbostic crmode(); 5341198Sbostic } 5441198Sbostic 5541198Sbostic 5641198Sbostic ExitChess() 5741198Sbostic { 5841198Sbostic nocrmode(); 5941198Sbostic endwin(); 6041198Sbostic exit(0); 6141198Sbostic } 6241198Sbostic 6341198Sbostic 64*46740Sbostic void 6541198Sbostic Die() 6641198Sbostic { 6741198Sbostic char s[80]; 6841198Sbostic signal(SIGINT,SIG_IGN); 6941198Sbostic signal(SIGQUIT,SIG_IGN); 7041198Sbostic ShowMessage("Abort? "); 7141198Sbostic scanz("%s",s); 7241198Sbostic if (strcmp(s,"yes") == 0) ExitChess(); 7341198Sbostic signal(SIGINT,Die); signal(SIGQUIT,Die); 7441198Sbostic } 7541198Sbostic 7641198Sbostic 77*46740Sbostic void 7841198Sbostic TerminateSearch() 7941198Sbostic { 8041198Sbostic signal(SIGINT,SIG_IGN); 8141198Sbostic signal(SIGQUIT,SIG_IGN); 8241198Sbostic timeout = true; 8341198Sbostic bothsides = false; 8441198Sbostic signal(SIGINT,Die); signal(SIGQUIT,Die); 8541198Sbostic } 8641198Sbostic 8741198Sbostic 8841198Sbostic InputCommand() 8941198Sbostic 9041198Sbostic /* 9141198Sbostic Process the users command. If easy mode is OFF (the computer is 9241198Sbostic thinking on opponents time) and the program is out of book, then make 9341198Sbostic the 'hint' move on the board and call SelectMove() to find a response. 9441198Sbostic The user terminates the search by entering ^C (quit siqnal) before 9541198Sbostic entering a command. If the opponent does not make the hint move, then 9641198Sbostic set Sdepth to zero. 9741198Sbostic */ 9841198Sbostic 9941198Sbostic { 10041198Sbostic short ok,i,tmp; 10141198Sbostic long cnt,rate,t1,t2; 10241198Sbostic unsigned short mv; 10341198Sbostic char s[80]; 10441198Sbostic 10541198Sbostic ok = quit = false; 10641198Sbostic player = opponent; 10741198Sbostic ShowSidetomove(); 10841198Sbostic ft = 0; 10941198Sbostic if (hint > 0 && !easy && Book == NULL) 11041198Sbostic { 11141198Sbostic fflush(stdout); 11241198Sbostic time0 = time((long *)0); 11341198Sbostic algbr(hint>>8,hint & 0xFF,false); 11441198Sbostic strcpy(s,mvstr1); 11541198Sbostic tmp = epsquare; 11641198Sbostic if (VerifyMove(s,1,&mv)) 11741198Sbostic { 11841198Sbostic PromptForMove(); 11941198Sbostic SelectMove(computer,2); 12041198Sbostic VerifyMove(mvstr1,2,&mv); 12141198Sbostic if (Sdepth > 0) Sdepth--; 12241198Sbostic } 123*46740Sbostic ft = time((time_t *)0) - time0; 12441198Sbostic epsquare = tmp; 12541198Sbostic } 12641198Sbostic 12741198Sbostic signal(SIGINT,Die); signal(SIGQUIT,Die); 12841198Sbostic while (!(ok || quit)) 12941198Sbostic { 13041198Sbostic PromptForMove(); 13141198Sbostic scanz("%s",s); 13241198Sbostic player = opponent; 13341198Sbostic ok = VerifyMove(s,0,&mv); 13441198Sbostic if (ok && mv != hint) 13541198Sbostic { 13641198Sbostic Sdepth = 0; 13741198Sbostic ft = 0; 13841198Sbostic } 13941198Sbostic 14041198Sbostic if (strcmp(s,"bd") == 0) 14141198Sbostic { 14241198Sbostic ClrScreen(); 14341198Sbostic UpdateDisplay(0,0,1,0); 14441198Sbostic } 14541198Sbostic if (strcmp(s,"quit") == 0) quit = true; 14641198Sbostic if (strcmp(s,"post") == 0) post = !post; 14741198Sbostic if (strcmp(s,"edit") == 0) EditBoard(); 14841198Sbostic if (strcmp(s,"go") == 0) ok = true; 14941198Sbostic if (strcmp(s,"help") == 0) help(); 15041198Sbostic if (strcmp(s,"force") == 0) force = !force; 15141198Sbostic if (strcmp(s,"book") == 0) Book = NULL; 15241198Sbostic if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo(); 15341198Sbostic if (strcmp(s,"new") == 0) NewGame(); 15441198Sbostic if (strcmp(s,"list") == 0) ListGame(); 15541198Sbostic if (strcmp(s,"level") == 0) SelectLevel(); 15641198Sbostic if (strcmp(s,"hash") == 0) hashflag = !hashflag; 15741198Sbostic if (strcmp(s,"beep") == 0) beep = !beep; 15841198Sbostic if (strcmp(s,"Awindow") == 0) ChangeAlphaWindow(); 15941198Sbostic if (strcmp(s,"Bwindow") == 0) ChangeBetaWindow(); 16041198Sbostic if (strcmp(s,"hint") == 0) GiveHint(); 16141198Sbostic if (strcmp(s,"both") == 0) 16241198Sbostic { 16341198Sbostic bothsides = !bothsides; 16441198Sbostic Sdepth = 0; 16541198Sbostic SelectMove(opponent,1); 16641198Sbostic ok = true; 16741198Sbostic } 16841198Sbostic if (strcmp(s,"reverse") == 0) 16941198Sbostic { 17041198Sbostic reverse = !reverse; 17141198Sbostic ClrScreen(); 17241198Sbostic UpdateDisplay(0,0,1,0); 17341198Sbostic } 17441198Sbostic if (strcmp(s,"switch") == 0) 17541198Sbostic { 17641198Sbostic computer = otherside[computer]; 17741198Sbostic opponent = otherside[opponent]; 17841198Sbostic force = false; 17941198Sbostic Sdepth = 0; 18041198Sbostic ok = true; 18141198Sbostic } 18241198Sbostic if (strcmp(s,"white") == 0) 18341198Sbostic { 18441198Sbostic computer = white; opponent = black; 18541198Sbostic ok = true; force = false; 18641198Sbostic Sdepth = 0; 18741198Sbostic } 18841198Sbostic if (strcmp(s,"black") == 0) 18941198Sbostic { 19041198Sbostic computer = black; opponent = white; 19141198Sbostic ok = true; force = false; 19241198Sbostic Sdepth = 0; 19341198Sbostic } 19441198Sbostic if (strcmp(s,"remove") == 0 && GameCnt >= 1) 19541198Sbostic { 19641198Sbostic Undo(); Undo(); 19741198Sbostic } 19841198Sbostic if (strcmp(s,"get") == 0) GetGame(); 19941198Sbostic if (strcmp(s,"save") == 0) SaveGame(); 20041198Sbostic if (strcmp(s,"depth") == 0) ChangeSearchDepth(); 20141198Sbostic if (strcmp(s,"random") == 0) dither = 6; 20241198Sbostic if (strcmp(s,"easy") == 0) easy = !easy; 20341198Sbostic if (strcmp(s,"contempt") == 0) SetContempt(); 20441198Sbostic if (strcmp(s,"xwndw") == 0) ChangeXwindow(); 20541198Sbostic if (strcmp(s,"test") == 0) 20641198Sbostic { 20741198Sbostic t1 = time(0); 20841198Sbostic cnt = 0; 20941198Sbostic for (i = 0; i < 10000; i++) 21041198Sbostic { 21141198Sbostic MoveList(opponent,2); 21241198Sbostic cnt += TrPnt[3] - TrPnt[2]; 21341198Sbostic } 21441198Sbostic t2 = time(0); 21541198Sbostic rate = cnt / (t2-t1); 21641198Sbostic gotoXY(50,24); 21741198Sbostic printz("cnt= %ld rate= %ld",cnt,rate); 21841198Sbostic ClrEoln(); 21941198Sbostic } 22041198Sbostic if (strcmp(s,"p") == 0) ShowPostnValues(); 22141198Sbostic if (strcmp(s,"debug") == 0) DoDebug(); 22241198Sbostic } 22341198Sbostic 22441198Sbostic ClearMessage(); 22541198Sbostic ElapsedTime(1); 22641198Sbostic if (force) 22741198Sbostic { 22841198Sbostic computer = opponent; opponent = otherside[computer]; 22941198Sbostic } 23041198Sbostic (void) times(&tmbuf1); 23141198Sbostic signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch); 23241198Sbostic } 23341198Sbostic 23441198Sbostic 23541198Sbostic EditBoard() 23641198Sbostic 23741198Sbostic /* 23841198Sbostic Set up a board position. Pieces are entered by typing the piece 23941198Sbostic followed by the location. For example, Nf3 will place a knight on 24041198Sbostic square f3. 24141198Sbostic */ 24241198Sbostic 24341198Sbostic { 24441198Sbostic short a,r,c,sq; 24541198Sbostic char s[80]; 24641198Sbostic 24741198Sbostic ClrScreen(); 24841198Sbostic UpdateDisplay(0,0,1,0); 24941198Sbostic gotoXY(50,2); printz(". Exit to main"); 25041198Sbostic gotoXY(50,3); printz("# Clear board"); 25141198Sbostic gotoXY(49,5); printz("Enter piece & location: "); 25241198Sbostic a = white; 25341198Sbostic do 25441198Sbostic { 25541198Sbostic gotoXY(73,5); ClrEoln(); scanz("%s",s); 25641198Sbostic if (s[0] == '#') 25741198Sbostic { 25841198Sbostic for (sq = 0; sq < 64; sq++) 25941198Sbostic { 26041198Sbostic board[sq] = no_piece; color[sq] = neutral; 26141198Sbostic } 26241198Sbostic UpdateDisplay(0,0,1,0); 26341198Sbostic } 26441198Sbostic if (s[0] == 'c' || s[0] == 'C') a = otherside[a]; 26541198Sbostic c = s[1]-'a'; r = s[2]-'1'; 26641198Sbostic if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8)) 26741198Sbostic { 26841198Sbostic sq = locn[r][c]; 26941198Sbostic color[sq] = a; 27041198Sbostic if (s[0] == 'p') board[sq] = pawn; 27141198Sbostic else if (s[0] == 'n') board[sq] = knight; 27241198Sbostic else if (s[0] == 'b') board[sq] = bishop; 27341198Sbostic else if (s[0] == 'r') board[sq] = rook; 27441198Sbostic else if (s[0] == 'q') board[sq] = queen; 27541198Sbostic else if (s[0] == 'k') board[sq] = king; 27641198Sbostic else { board[sq] = no_piece; color[sq] = neutral; } 27741198Sbostic DrawPiece(sq); 27841198Sbostic } 27941198Sbostic } 28041198Sbostic while (s[0] != '.'); 28141198Sbostic if (board[4] != king) kingmoved[white] = 10; 28241198Sbostic if (board[60] != king) kingmoved[black] = 10; 28341198Sbostic GameCnt = -1; Game50 = 0; Sdepth = 0; 28441198Sbostic InitializeStats(); 28541198Sbostic ClrScreen(); 28641198Sbostic UpdateDisplay(0,0,1,0); 28741198Sbostic } 28841198Sbostic 28941198Sbostic 29041198Sbostic help() 29141198Sbostic { 29241198Sbostic ClrScreen(); 29341198Sbostic gotoXY(28,1); printz("CHESS command summary"); 29441198Sbostic gotoXY(1,3); printz("g1f3 move from g1 to f3"); 29541198Sbostic gotoXY(1,4); printz("nf3 move knight to f3"); 29641198Sbostic gotoXY(1,5); printz("o-o castle king side"); 29741198Sbostic gotoXY(1,6); printz("o-o-o castle queen side"); 29841198Sbostic gotoXY(1,7); printz("edit edit board"); 29941198Sbostic gotoXY(1,8); printz("switch sides with computer"); 30041198Sbostic gotoXY(1,9); printz("white computer plays white"); 30141198Sbostic gotoXY(1,10); printz("black computer plays black"); 30241198Sbostic gotoXY(1,11); printz("reverse board display"); 30341198Sbostic gotoXY(1,12); printz("both computer match"); 30441198Sbostic gotoXY(1,13); printz("random randomize play"); 30541198Sbostic gotoXY(1,14); printz("undo undo last move"); 30641198Sbostic gotoXY(42,3); printz("level change level"); 30741198Sbostic gotoXY(42,4); printz("depth set search depth"); 30841198Sbostic gotoXY(42,5); printz("post principle variation"); 30941198Sbostic gotoXY(42,6); printz("hint suggest a move"); 31041198Sbostic gotoXY(42,7); printz("bd redraw board"); 31141198Sbostic gotoXY(42,8); printz("force enter game moves"); 31241198Sbostic gotoXY(42,9); printz("list game to chess.lst"); 31341198Sbostic gotoXY(42,10); printz("save game to file"); 31441198Sbostic gotoXY(42,11); printz("get game from file"); 31541198Sbostic gotoXY(42,12); printz("new start new game"); 31641198Sbostic gotoXY(42,13); printz("quit exit CHESS"); 31741198Sbostic gotoXY(10,21); printz("Computer: "); 31841198Sbostic if (computer == white) printz("WHITE"); else printz("BLACK"); 31941198Sbostic gotoXY(10,22); printz("Opponent: "); 32041198Sbostic if (opponent == white) printz("WHITE"); else printz("BLACK"); 32141198Sbostic gotoXY(10,23); printz("Level: %ld",Level," sec."); 32241198Sbostic gotoXY(10,24); printz("Easy mode: "); 32341198Sbostic if (easy) printz("ON"); else printz("OFF"); 32441198Sbostic gotoXY(40,21); printz("Depth: %d",MaxSearchDepth); 32541198Sbostic gotoXY(40,22); printz("Random: "); 32641198Sbostic if (dither) printz("ON"); else printz("OFF"); 32741198Sbostic gotoXY(40,23); printz("Transposition table: "); 32841198Sbostic if (hashflag) printz("ON"); else printz("OFF"); 32941198Sbostic refresh(); 33041198Sbostic while (getchar() != 27); 33141198Sbostic ClrScreen(); 33241198Sbostic UpdateDisplay(0,0,1,0); 33341198Sbostic } 33441198Sbostic 33541198Sbostic 33641198Sbostic ShowDepth(ch) 33741198Sbostic char ch; 33841198Sbostic { 33941198Sbostic gotoXY(50,4); printz("Depth= %d%c ",Sdepth,ch); ClrEoln(); 34041198Sbostic } 34141198Sbostic 34241198Sbostic 34341198Sbostic ShowResults(score,bstline,ch) 34441198Sbostic short score; 34541198Sbostic unsigned short bstline[]; 34641198Sbostic char ch; 34741198Sbostic { 34841198Sbostic short d,e,ply; 34941198Sbostic if (post && player == computer) 35041198Sbostic { 35141198Sbostic e = lpost; 35241198Sbostic gotoXY(50,5); printz("Score= %d",score); ClrEoln(); 35341198Sbostic d = 8; gotoXY(50,d); ClrEoln(); 35441198Sbostic for (ply = 1; bstline[ply] > 0; ply++) 35541198Sbostic { 35641198Sbostic algbr(bstline[ply] >> 8,bstline[ply] & 0xFF,false); 35741198Sbostic if (ply == 5 || ply == 9 || ply == 13 || ply == 17) 35841198Sbostic { 35941198Sbostic gotoXY(50,++d); ClrEoln(); 36041198Sbostic } 36141198Sbostic printz("%5s ",mvstr1); 36241198Sbostic } 36341198Sbostic ClrEoln(); 36441198Sbostic lpost = d; 36541198Sbostic while (++d <= e) 36641198Sbostic { 36741198Sbostic gotoXY(50,d); ClrEoln(); 36841198Sbostic } 36941198Sbostic } 37041198Sbostic } 37141198Sbostic 37241198Sbostic 37341198Sbostic SearchStartStuff(side) 37441198Sbostic short side; 37541198Sbostic { 37641198Sbostic short i; 37741198Sbostic signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch); 37841198Sbostic if (player == computer) 37941198Sbostic for (i = 5; i < 14; i++) 38041198Sbostic { 38141198Sbostic gotoXY(50,i); ClrEoln(); 38241198Sbostic } 38341198Sbostic } 38441198Sbostic 38541198Sbostic 38641198Sbostic OutputMove() 38741198Sbostic { 38841198Sbostic if (root->flags & epmask) UpdateDisplay(0,0,1,0); 38941198Sbostic else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask); 39041198Sbostic gotoXY(50,17); printz("My move is: %s",mvstr1); 39141198Sbostic if (beep) putchar(7); 39241198Sbostic ClrEoln(); 39341198Sbostic 39441198Sbostic gotoXY(50,24); 39541198Sbostic if (root->flags & draw) printz("Draw game!"); 39641198Sbostic else if (root->score == -9999) printz("opponent mates!"); 39741198Sbostic else if (root->score == 9998) printz("computer mates!"); 39841198Sbostic else if (root->score < -9000) printz("opponent will soon mate!"); 39941198Sbostic else if (root->score > 9000) printz("computer will soon mate!"); 40041198Sbostic ClrEoln(); 40141198Sbostic 40241198Sbostic if (post) 40341198Sbostic { 40441198Sbostic gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); ClrEoln(); 40541198Sbostic gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); ClrEoln(); 40641198Sbostic } 40741198Sbostic } 40841198Sbostic 40941198Sbostic 41041198Sbostic ElapsedTime(iop) 41141198Sbostic 41241198Sbostic /* 41341198Sbostic Determine the time that has passed since the search was started. If 41441198Sbostic the elapsed time exceeds the target (ResponseTime+ExtraTime) then set 41541198Sbostic timeout to true which will terminate the search. 41641198Sbostic */ 41741198Sbostic 41841198Sbostic short iop; 41941198Sbostic { 420*46740Sbostic et = time((time_t *)0) - time0; 42141198Sbostic if (et < 0) et = 0; 42241198Sbostic ETnodes += 50; 42341198Sbostic if (et > et0 || iop == 1) 42441198Sbostic { 42541198Sbostic if (et > ResponseTime+ExtraTime && Sdepth > 1) timeout = true; 42641198Sbostic et0 = et; 42741198Sbostic if (iop == 1) 42841198Sbostic { 429*46740Sbostic time0 = time((time_t *)0); et0 = 0; 43041198Sbostic } 43141198Sbostic (void) times(&tmbuf2); 43241198Sbostic cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ; 43341198Sbostic if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft); 43441198Sbostic else evrate = 0; 43541198Sbostic ETnodes = NodeCnt + 50; 43641198Sbostic UpdateClocks(); 43741198Sbostic } 43841198Sbostic } 43941198Sbostic 44041198Sbostic 44141198Sbostic UpdateClocks() 44241198Sbostic { 44341198Sbostic short m,s; 44441198Sbostic m = et/60; s = (et - 60*m); 44541198Sbostic if (TCflag) 44641198Sbostic { 44741198Sbostic m = (TimeControl.clock[player] - et) / 60; 44841198Sbostic s = TimeControl.clock[player] - et - 60*m; 44941198Sbostic } 45041198Sbostic if (m < 0) m = 0; 45141198Sbostic if (s < 0) s = 0; 45241198Sbostic if (player == white) 45341198Sbostic if (reverse) gotoXY(20,2); else gotoXY(20,23); 45441198Sbostic else 45541198Sbostic if (reverse) gotoXY(20,23); else gotoXY(20,2); 45641198Sbostic printz("%d:%2d ",m,s); 45741198Sbostic if (post) 45841198Sbostic { 45941198Sbostic gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); 46041198Sbostic gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); 46141198Sbostic } 46241198Sbostic refresh(); 46341198Sbostic } 46441198Sbostic 46541198Sbostic 46641198Sbostic 46741198Sbostic SetTimeControl() 46841198Sbostic { 46941198Sbostic if (TCflag) 47041198Sbostic { 47141198Sbostic TimeControl.moves[white] = TimeControl.moves[black] = TCmoves; 47241198Sbostic TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes; 47341198Sbostic } 47441198Sbostic else 47541198Sbostic { 47641198Sbostic TimeControl.moves[white] = TimeControl.moves[black] = 0; 47741198Sbostic TimeControl.clock[white] = TimeControl.clock[black] = 0; 47841198Sbostic Level = 60*(long)TCminutes; 47941198Sbostic } 48041198Sbostic et = 0; 48141198Sbostic ElapsedTime(1); 48241198Sbostic } 48341198Sbostic 48441198Sbostic 48541198Sbostic gotoXY(x,y) 48641198Sbostic short x,y; 48741198Sbostic { 48841198Sbostic move(y-1,x-1); 48941198Sbostic } 49041198Sbostic 49141198Sbostic 49241198Sbostic ClrScreen() 49341198Sbostic { 49441198Sbostic clear(); refresh(); 49541198Sbostic } 49641198Sbostic 49741198Sbostic 49841198Sbostic ClrEoln() 49941198Sbostic { 50041198Sbostic clrtoeol(); refresh(); 50141198Sbostic } 50241198Sbostic 50341198Sbostic 50441198Sbostic DrawPiece(sq) 50541198Sbostic short sq; 50641198Sbostic { 50741198Sbostic short r,c; char x; 50841198Sbostic if (reverse) r = 7-row[sq]; else r = row[sq]; 50941198Sbostic if (reverse) c = 7-column[sq]; else c = column[sq]; 51041198Sbostic if (color[sq] == black) x = '*'; else x = ' '; 51141198Sbostic gotoXY(5+5*c,5+2*(7-r)); printz("%c%c ",x,pxx[board[sq]]); 51241198Sbostic } 51341198Sbostic 51441198Sbostic 51541198Sbostic UpdateDisplay(f,t,flag,iscastle) 51641198Sbostic short f,t,flag,iscastle; 51741198Sbostic { 51841198Sbostic short i,l,z; 51941198Sbostic if (flag) 52041198Sbostic { 52141198Sbostic gotoXY(56,2); printz("CHESS"); 52241198Sbostic i = 3; 52341198Sbostic gotoXY(3,++i); 52441198Sbostic printz("|----|----|----|----|----|----|----|----|"); 52541198Sbostic while (i<19) 52641198Sbostic { 52741198Sbostic gotoXY(1,++i); 52841198Sbostic if (reverse) z = (i/2)-1; else z = 10-(i/2); 52941198Sbostic printz("%d | | | | | | | | |",z); 53041198Sbostic gotoXY(3,++i); 53141198Sbostic if (i < 19) 53241198Sbostic printz("+----+----+----+----+----+----+----+----+"); 53341198Sbostic } 53441198Sbostic printz("|----|----|----|----|----|----|----|----|"); 53541198Sbostic gotoXY(3,21); 53641198Sbostic if (reverse) printz(" h g f e d c b a"); 53741198Sbostic else printz(" a b c d e f g h"); 53841198Sbostic if (reverse) gotoXY(5,23); else gotoXY(5,2); 53941198Sbostic if (computer == black) printz("Computer"); else printz("Human "); 54041198Sbostic if (reverse) gotoXY(5,2); else gotoXY(5,23); 54141198Sbostic if (computer == white) printz("Computer"); else printz("Human "); 54241198Sbostic for (l = 0; l < 64; l++) DrawPiece(l); 54341198Sbostic } 54441198Sbostic else 54541198Sbostic { 54641198Sbostic DrawPiece(f); DrawPiece(t); 54741198Sbostic if (iscastle) 54841198Sbostic if (t > f) 54941198Sbostic { DrawPiece(f+3); DrawPiece(t-1); } 55041198Sbostic else 55141198Sbostic { DrawPiece(f-4); DrawPiece(t+1); } 55241198Sbostic } 55341198Sbostic refresh(); 55441198Sbostic } 55541198Sbostic 55641198Sbostic 55741198Sbostic GetOpenings() 55841198Sbostic 55941198Sbostic /* 56041198Sbostic Read in the Opening Book file and parse the algebraic notation for a 56141198Sbostic move into an unsigned integer format indicating the from and to 56241198Sbostic square. Create a linked list of opening lines of play, with 56341198Sbostic entry->next pointing to the next line and entry->move pointing to a 56441198Sbostic chunk of memory containing the moves. More Opening lines of up to 256 56541198Sbostic half moves may be added to gnuchess.book. 56641198Sbostic */ 56741198Sbostic 56841198Sbostic { 56941198Sbostic FILE *fd; 57041198Sbostic int c,i,j,side; 57141198Sbostic struct BookEntry *entry; 57241198Sbostic unsigned short mv,*mp,tmp[100]; 57341198Sbostic 57441199Sbostic if ((fd = fopen(_PATH_CHESSBOOK,"r")) != NULL) 57541198Sbostic { 57641198Sbostic Book = NULL; 57741198Sbostic i = 0; side = white; 57841198Sbostic while ((c = parse(fd,&mv,side)) >= 0) 57941198Sbostic if (c == 1) 58041198Sbostic { 58141198Sbostic tmp[++i] = mv; 58241198Sbostic side = otherside[side]; 58341198Sbostic } 58441198Sbostic else if (c == 0 && i > 0) 58541198Sbostic { 58641198Sbostic entry = (struct BookEntry *)malloc(sizeof(struct BookEntry)); 58741198Sbostic mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short)); 58841198Sbostic entry->mv = mp; 58941198Sbostic entry->next = Book; 59041198Sbostic Book = entry; 59141198Sbostic for (j = 1; j <= i; j++) *(mp++) = tmp[j]; 59241198Sbostic *mp = 0; 59341198Sbostic i = 0; side = white; 59441198Sbostic } 59541198Sbostic fclose(fd); 59641198Sbostic } 59741199Sbostic else 59841199Sbostic { 59941199Sbostic fprintf(stderr, "\nchess: can't read %s.\n", _PATH_CHESSBOOK); 60041199Sbostic exit(1); 60141199Sbostic } 60241198Sbostic } 60341198Sbostic 60441198Sbostic 60541198Sbostic int parse(fd,mv,side) 60641198Sbostic FILE *fd; 60741198Sbostic unsigned short *mv; 60841198Sbostic short side; 60941198Sbostic { 61041198Sbostic int c,i,r1,r2,c1,c2; 61141198Sbostic char s[100]; 61241198Sbostic while ((c = getc(fd)) == ' '); 61341198Sbostic i = 0; s[0] = c; 61441198Sbostic while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd); 61541198Sbostic s[++i] = '\0'; 61641198Sbostic if (c == EOF) return(-1); 61741198Sbostic if (s[0] == '!' || i < 3) 61841198Sbostic { 61941198Sbostic while (c != '\n' && c != EOF) c = getc(fd); 62041198Sbostic return(0); 62141198Sbostic } 62241198Sbostic if (s[4] == 'o') 62341198Sbostic if (side == black) *mv = 0x3C3A; else *mv = 0x0402; 62441198Sbostic else if (s[0] == 'o') 62541198Sbostic if (side == black) *mv = 0x3C3E; else *mv = 0x0406; 62641198Sbostic else 62741198Sbostic { 62841198Sbostic c1 = s[0] - 'a'; r1 = s[1] - '1'; 62941198Sbostic c2 = s[2] - 'a'; r2 = s[3] - '1'; 63041198Sbostic *mv = (locn[r1][c1]<<8) + locn[r2][c2]; 63141198Sbostic } 63241198Sbostic return(1); 63341198Sbostic } 63441198Sbostic 63541198Sbostic 63641198Sbostic GetGame() 63741198Sbostic { 63841198Sbostic FILE *fd; 63941198Sbostic char fname[40]; 64041198Sbostic int c; 64141198Sbostic short sq; 64241198Sbostic unsigned short m; 64341198Sbostic 64441198Sbostic ShowMessage("File name: "); 64541198Sbostic scanz("%s",fname); 64641198Sbostic if (fname[0] == '\0') strcpy(fname,"chess.000"); 64741198Sbostic if ((fd = fopen(fname,"r")) != NULL) 64841198Sbostic { 64941198Sbostic fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50); 65041198Sbostic fscanf(fd,"%hd%hd%hd%hd", 65141198Sbostic &castld[white],&castld[black], 65241198Sbostic &kingmoved[white],&kingmoved[black]); 65341198Sbostic fscanf(fd,"%hd%hd",&TCflag,&OperatorTime); 65441198Sbostic fscanf(fd,"%ld%ld%hd%hd", 65541198Sbostic &TimeControl.clock[white],&TimeControl.clock[black], 65641198Sbostic &TimeControl.moves[white],&TimeControl.moves[black]); 65741198Sbostic for (sq = 0; sq < 64; sq++) 65841198Sbostic { 65941198Sbostic fscanf(fd,"%hd",&m); 66041198Sbostic board[sq] = (m >> 8); color[sq] = (m & 0xFF); 66141198Sbostic if (color[sq] == 0) color[sq] = neutral; else --color[sq]; 66241198Sbostic } 66341198Sbostic GameCnt = -1; c = '?'; 66441198Sbostic while (c != EOF) 66541198Sbostic { 66641198Sbostic ++GameCnt; 66741198Sbostic c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove, 66841198Sbostic &GameList[GameCnt].score,&GameList[GameCnt].depth, 66941198Sbostic &GameList[GameCnt].nodes,&GameList[GameCnt].time, 67041198Sbostic &GameList[GameCnt].piece,&GameList[GameCnt].color); 67141198Sbostic if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral; 67241198Sbostic else --GameList[GameCnt].color; 67341198Sbostic } 67441198Sbostic GameCnt--; 67541198Sbostic if (TimeControl.clock[white] > 0) TCflag = true; 67641198Sbostic computer--; opponent--; 67741198Sbostic } 67841198Sbostic fclose(fd); 67941198Sbostic InitializeStats(); 68041198Sbostic UpdateDisplay(0,0,1,0); 68141198Sbostic Sdepth = 0; 68241198Sbostic } 68341198Sbostic 68441198Sbostic 68541198Sbostic SaveGame() 68641198Sbostic { 68741198Sbostic FILE *fd; 68841198Sbostic char fname[40]; 68941198Sbostic short sq,i,c; 69041198Sbostic 69141198Sbostic ShowMessage("File name: "); 69241198Sbostic scanz("%s",fname); 69341198Sbostic 69441198Sbostic if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000"); 69541198Sbostic fd = fopen(fname,"w"); 69641198Sbostic fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50); 69741198Sbostic fprintf(fd,"%d %d %d %d\n", 69841198Sbostic castld[white],castld[black],kingmoved[white],kingmoved[black]); 69941198Sbostic fprintf(fd,"%d %d\n",TCflag,OperatorTime); 70041198Sbostic fprintf(fd,"%ld %ld %d %d\n", 70141198Sbostic TimeControl.clock[white],TimeControl.clock[black], 70241198Sbostic TimeControl.moves[white],TimeControl.moves[black]); 70341198Sbostic for (sq = 0; sq < 64; sq++) 70441198Sbostic { 70541198Sbostic if (color[sq] == neutral) c = 0; else c = color[sq]+1; 70641198Sbostic fprintf(fd,"%d\n",256*board[sq] + c); 70741198Sbostic } 70841198Sbostic for (i = 0; i <= GameCnt; i++) 70941198Sbostic { 71041198Sbostic if (GameList[i].color == neutral) c = 0; 71141198Sbostic else c = GameList[i].color + 1; 71241198Sbostic fprintf(fd,"%d %d %d %ld %d %d %d\n", 71341198Sbostic GameList[i].gmove,GameList[i].score,GameList[i].depth, 71441198Sbostic GameList[i].nodes,GameList[i].time, 71541198Sbostic GameList[i].piece,c); 71641198Sbostic } 71741198Sbostic fclose(fd); 71841198Sbostic } 71941198Sbostic 72041198Sbostic 72141198Sbostic ListGame() 72241198Sbostic { 72341198Sbostic FILE *fd; 72441198Sbostic short i,f,t; 72541198Sbostic fd = fopen("chess.lst","w"); 72641198Sbostic fprintf(fd,"\n"); 72741198Sbostic fprintf(fd," score depth nodes time "); 72841198Sbostic fprintf(fd," score depth nodes time\n"); 72941198Sbostic for (i = 0; i <= GameCnt; i++) 73041198Sbostic { 73141198Sbostic f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF); 73241198Sbostic algbr(f,t,false); 73341198Sbostic if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," "); 73441198Sbostic fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1, 73541198Sbostic GameList[i].score,GameList[i].depth, 73641198Sbostic GameList[i].nodes,GameList[i].time); 73741198Sbostic } 73841198Sbostic fprintf(fd,"\n\n"); 73941198Sbostic fclose(fd); 74041198Sbostic } 74141198Sbostic 74241198Sbostic 74341198Sbostic Undo() 74441198Sbostic 74541198Sbostic /* 74641198Sbostic Undo the most recent half-move. 74741198Sbostic */ 74841198Sbostic 74941198Sbostic { 75041198Sbostic short f,t; 75141198Sbostic f = GameList[GameCnt].gmove>>8; 75241198Sbostic t = GameList[GameCnt].gmove & 0xFF; 75341198Sbostic if (board[t] == king && distance(t,f) > 1) 75441198Sbostic castle(GameList[GameCnt].color,f,t,2); 75541198Sbostic else 75641198Sbostic { 75741198Sbostic board[f] = board[t]; color[f] = color[t]; 75841198Sbostic board[t] = GameList[GameCnt].piece; 75941198Sbostic color[t] = GameList[GameCnt].color; 76041198Sbostic if (board[f] == king) --kingmoved[color[f]]; 76141198Sbostic } 76241198Sbostic if (TCflag) ++TimeControl.moves[color[f]]; 76341198Sbostic GameCnt--; mate = false; Sdepth = 0; 76441198Sbostic UpdateDisplay(0,0,1,0); 76541198Sbostic InitializeStats(); 76641198Sbostic } 76741198Sbostic 76841198Sbostic 76941198Sbostic ShowMessage(s) 77041198Sbostic char *s; 77141198Sbostic { 77241198Sbostic gotoXY(50,24); printz("%s",s); ClrEoln(); 77341198Sbostic } 77441198Sbostic 77541198Sbostic ClearMessage() 77641198Sbostic { 77741198Sbostic gotoXY(50,24); ClrEoln(); 77841198Sbostic } 77941198Sbostic 78041198Sbostic ShowSidetomove() 78141198Sbostic { 78241198Sbostic gotoXY(50,14); 78341198Sbostic if (player == white) printz("%2d: WHITE",1+(GameCnt+1)/2); 78441198Sbostic else printz("%2d: BLACK",1+(GameCnt+1)/2); 78541198Sbostic ClrEoln(); 78641198Sbostic } 78741198Sbostic 78841198Sbostic PromptForMove() 78941198Sbostic { 79041198Sbostic gotoXY(50,19); printz("Your move is? "); ClrEoln(); 79141198Sbostic } 79241198Sbostic 79341198Sbostic ShowCurrentMove(pnt,f,t) 79441198Sbostic short pnt,f,t; 79541198Sbostic { 79641198Sbostic algbr(f,t,false); 79741198Sbostic gotoXY(50,7); printz("(%2d) %4s",pnt,mvstr1); 79841198Sbostic } 79941198Sbostic 80041198Sbostic ChangeAlphaWindow() 80141198Sbostic { 80241198Sbostic ShowMessage("window: "); 80341198Sbostic scanz("%hd",&Awindow); 80441198Sbostic } 80541198Sbostic 80641198Sbostic ChangeBetaWindow() 80741198Sbostic { 80841198Sbostic ShowMessage("window: "); 80941198Sbostic scanz("%hd",&Bwindow); 81041198Sbostic } 81141198Sbostic 81241198Sbostic GiveHint() 81341198Sbostic { 81441198Sbostic char s[40]; 81541198Sbostic algbr((short)(hint>>8),(short)(hint & 0xFF),false); 81641198Sbostic strcpy(s,"try "); 81741198Sbostic strcat(s,mvstr1); 81841198Sbostic ShowMessage(s); 81941198Sbostic } 82041198Sbostic 82141198Sbostic ChangeSearchDepth() 82241198Sbostic { 82341198Sbostic ShowMessage("depth= "); 82441198Sbostic scanz("%hd",&MaxSearchDepth); 82541198Sbostic } 82641198Sbostic 82741198Sbostic SetContempt() 82841198Sbostic { 82941198Sbostic ShowMessage("contempt= "); 83041198Sbostic scanz("%hd",&contempt); 83141198Sbostic } 83241198Sbostic 83341198Sbostic ChangeXwindow() 83441198Sbostic { 83541198Sbostic ShowMessage("xwndw= "); 83641198Sbostic scanz("%hd",&xwndw); 83741198Sbostic } 83841198Sbostic 83941198Sbostic 84041198Sbostic SelectLevel() 84141198Sbostic { 84241198Sbostic ClrScreen(); 84341198Sbostic gotoXY(32,2); printz("CHESS"); 84441198Sbostic gotoXY(20,4); printz(" 1. 60 moves in 5 minutes"); 84541198Sbostic gotoXY(20,5); printz(" 2. 60 moves in 15 minutes"); 84641198Sbostic gotoXY(20,6); printz(" 3. 60 moves in 30 minutes"); 84741198Sbostic gotoXY(20,7); printz(" 4. 40 moves in 30 minutes"); 84841198Sbostic gotoXY(20,8); printz(" 5. 40 moves in 60 minutes"); 84941198Sbostic gotoXY(20,9); printz(" 6. 40 moves in 120 minutes"); 85041198Sbostic gotoXY(20,10); printz(" 7. 40 moves in 240 minutes"); 85141198Sbostic gotoXY(20,11); printz(" 8. 1 move in 15 minutes"); 85241198Sbostic gotoXY(20,12); printz(" 9. 1 move in 60 minutes"); 85341198Sbostic gotoXY(20,13); printz("10. 1 move in 600 minutes"); 85441198Sbostic 85541198Sbostic OperatorTime = 0; TCmoves = 60; TCminutes = 5; 85641198Sbostic 85741198Sbostic gotoXY(20,17); printz("Enter Level: "); 85841198Sbostic refresh(); 85941198Sbostic scanz("%ld",&Level); 86041198Sbostic switch (Level) 86141198Sbostic { 86241198Sbostic case 1 : TCmoves = 60; TCminutes = 5; break; 86341198Sbostic case 2 : TCmoves = 60; TCminutes = 15; break; 86441198Sbostic case 3 : TCmoves = 60; TCminutes = 30; break; 86541198Sbostic case 4 : TCmoves = 40; TCminutes = 30; break; 86641198Sbostic case 5 : TCmoves = 40; TCminutes = 60; break; 86741198Sbostic case 6 : TCmoves = 40; TCminutes = 120; break; 86841198Sbostic case 7 : TCmoves = 40; TCminutes = 240; break; 86941198Sbostic case 8 : TCmoves = 1; TCminutes = 15; break; 87041198Sbostic case 9 : TCmoves = 1; TCminutes = 60; break; 87141198Sbostic case 10 : TCmoves = 1; TCminutes = 600; break; 87241198Sbostic } 87341198Sbostic 87441198Sbostic TCflag = (TCmoves > 1); 87541198Sbostic SetTimeControl(); 87641198Sbostic ClrScreen(); 87741198Sbostic UpdateDisplay(0,0,1,0); 87841198Sbostic } 87941198Sbostic 88041198Sbostic 88141198Sbostic ShowPostnValues() 88241198Sbostic { 88341198Sbostic short i,r,c; 88441198Sbostic ExaminePosition(); 88541198Sbostic for (i = 0; i < 64; i++) 88641198Sbostic { 88741198Sbostic if (reverse) r = 7-row[i]; else r = row[i]; 88841198Sbostic if (reverse) c = 7-column[i]; else c = column[i]; 88941198Sbostic gotoXY(4+5*c,5+2*(7-r)); 89041198Sbostic c1 = color[i]; c2 = otherside[c1]; 89141198Sbostic PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2]; 89241198Sbostic atk1 = atak[c1]; atk2 = atak[c2]; 89341198Sbostic if (color[i] == neutral) printz(" "); 89441198Sbostic else printz("%3d ",SqValue(i,opponent)); 89541198Sbostic } 89641198Sbostic ScorePosition(opponent,&i); 89741198Sbostic gotoXY(50,24); 89841198Sbostic printz("Score= %d",i); ClrEoln(); 89941198Sbostic } 90041198Sbostic 90141198Sbostic 90241198Sbostic DoDebug() 90341198Sbostic { 90441198Sbostic short k,p,i,r,c,tp,tc; 90541198Sbostic char s[40]; 90641198Sbostic ExaminePosition(); 90741198Sbostic ShowMessage("Enter piece: "); 90841198Sbostic scanz("%s",s); 90941198Sbostic if (s[0] == 'w') k = white; else k = black; 91041198Sbostic if (s[1] == 'p') p = pawn; 91141198Sbostic else if (s[1] == 'n') p = knight; 91241198Sbostic else if (s[1] == 'b') p = bishop; 91341198Sbostic else if (s[1] == 'r') p = rook; 91441198Sbostic else if (s[1] == 'q') p = queen; 91541198Sbostic else if (s[1] == 'k') p = king; 91641198Sbostic else p = no_piece; 91741198Sbostic for (i = 0; i < 64; i++) 91841198Sbostic { 91941198Sbostic if (reverse) r = 7-row[i]; else r = row[i]; 92041198Sbostic if (reverse) c = 7-column[i]; else c = column[i]; 92141198Sbostic gotoXY(4+5*c,5+2*(7-r)); 92241198Sbostic tp = board[i]; tc = color[i]; 92341198Sbostic board[i] = p; color[i] = k; 92441198Sbostic c1 = k; c2 = otherside[c1]; 92541198Sbostic PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2]; 92641198Sbostic atk1 = atak[c1]; atk2 = atak[c2]; 92741198Sbostic printz("%3d ",SqValue(i,opponent)); 92841198Sbostic board[i] = tp; color[i] = tc; 92941198Sbostic } 93041198Sbostic ScorePosition(opponent,&i); 93141198Sbostic gotoXY(50,24); 93241198Sbostic printz("Score= %d",i); ClrEoln(); 93341198Sbostic } 934