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