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;
4246740Sbostic void TerminateSearch(),Die();
4341198Sbostic
4441198Sbostic #define scanz fflush(stdout),scanw
4541198Sbostic #define printz printw
4641198Sbostic
4741198Sbostic
Initialize()4841198Sbostic Initialize()
4941198Sbostic {
5041198Sbostic signal(SIGINT,Die); signal(SIGQUIT,Die);
5141198Sbostic initscr();
5241198Sbostic crmode();
5341198Sbostic }
5441198Sbostic
5541198Sbostic
ExitChess()5641198Sbostic ExitChess()
5741198Sbostic {
5841198Sbostic nocrmode();
5941198Sbostic endwin();
6041198Sbostic exit(0);
6141198Sbostic }
6241198Sbostic
6341198Sbostic
6446740Sbostic void
Die()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
7746740Sbostic void
TerminateSearch()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
InputCommand()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 }
12346740Sbostic 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
EditBoard()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
help()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
ShowDepth(ch)33641198Sbostic ShowDepth(ch)
33741198Sbostic char ch;
33841198Sbostic {
33941198Sbostic gotoXY(50,4); printz("Depth= %d%c ",Sdepth,ch); ClrEoln();
34041198Sbostic }
34141198Sbostic
34241198Sbostic
ShowResults(score,bstline,ch)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
SearchStartStuff(side)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
OutputMove()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
ElapsedTime(iop)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 {
42046740Sbostic 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 {
42946740Sbostic 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
UpdateClocks()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
SetTimeControl()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
gotoXY(x,y)48541198Sbostic gotoXY(x,y)
48641198Sbostic short x,y;
48741198Sbostic {
48841198Sbostic move(y-1,x-1);
48941198Sbostic }
49041198Sbostic
49141198Sbostic
ClrScreen()49241198Sbostic ClrScreen()
49341198Sbostic {
49441198Sbostic clear(); refresh();
49541198Sbostic }
49641198Sbostic
49741198Sbostic
ClrEoln()49841198Sbostic ClrEoln()
49941198Sbostic {
50041198Sbostic clrtoeol(); refresh();
50141198Sbostic }
50241198Sbostic
50341198Sbostic
DrawPiece(sq)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];
51056850Selan if (color[sq] == black) x = '*'; else x = ' ';
511*56890Selan gotoXY(5+5*c,5+2*(7-r)); printz("%c%c ",x,pxx[board[sq]]);
51241198Sbostic }
51341198Sbostic
51441198Sbostic
UpdateDisplay(f,t,flag,iscastle)51541198Sbostic UpdateDisplay(f,t,flag,iscastle)
51641198Sbostic short f,t,flag,iscastle;
51741198Sbostic {
51856850Selan short i,l,z,m = 0, j;
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);
52956850Selan printz("%d ", z);
53056850Selan for (j = 0; j < 8; j++) {
53156850Selan printz("|");
532*56890Selan if (j % 2 == m)
533*56890Selan printz("#");
534*56890Selan else
535*56890Selan printz(" ");
536*56890Selan printz(" ");
53756850Selan }
53856850Selan printz("|");
53956850Selan m = (m + 1) % 2;
54041198Sbostic gotoXY(3,++i);
54141198Sbostic if (i < 19)
54241198Sbostic printz("+----+----+----+----+----+----+----+----+");
54341198Sbostic }
54441198Sbostic printz("|----|----|----|----|----|----|----|----|");
54541198Sbostic gotoXY(3,21);
54641198Sbostic if (reverse) printz(" h g f e d c b a");
54741198Sbostic else printz(" a b c d e f g h");
54841198Sbostic if (reverse) gotoXY(5,23); else gotoXY(5,2);
54941198Sbostic if (computer == black) printz("Computer"); else printz("Human ");
55041198Sbostic if (reverse) gotoXY(5,2); else gotoXY(5,23);
55141198Sbostic if (computer == white) printz("Computer"); else printz("Human ");
55241198Sbostic for (l = 0; l < 64; l++) DrawPiece(l);
55341198Sbostic }
55441198Sbostic else
55541198Sbostic {
55641198Sbostic DrawPiece(f); DrawPiece(t);
55741198Sbostic if (iscastle)
55841198Sbostic if (t > f)
55941198Sbostic { DrawPiece(f+3); DrawPiece(t-1); }
56041198Sbostic else
56141198Sbostic { DrawPiece(f-4); DrawPiece(t+1); }
56241198Sbostic }
56341198Sbostic refresh();
56441198Sbostic }
56541198Sbostic
56641198Sbostic
GetOpenings()56741198Sbostic GetOpenings()
56841198Sbostic
56941198Sbostic /*
57041198Sbostic Read in the Opening Book file and parse the algebraic notation for a
57141198Sbostic move into an unsigned integer format indicating the from and to
57241198Sbostic square. Create a linked list of opening lines of play, with
57341198Sbostic entry->next pointing to the next line and entry->move pointing to a
57441198Sbostic chunk of memory containing the moves. More Opening lines of up to 256
57541198Sbostic half moves may be added to gnuchess.book.
57641198Sbostic */
57741198Sbostic
57841198Sbostic {
57941198Sbostic FILE *fd;
58041198Sbostic int c,i,j,side;
58141198Sbostic struct BookEntry *entry;
58241198Sbostic unsigned short mv,*mp,tmp[100];
58341198Sbostic
58441199Sbostic if ((fd = fopen(_PATH_CHESSBOOK,"r")) != NULL)
58541198Sbostic {
58641198Sbostic Book = NULL;
58741198Sbostic i = 0; side = white;
58841198Sbostic while ((c = parse(fd,&mv,side)) >= 0)
58941198Sbostic if (c == 1)
59041198Sbostic {
59141198Sbostic tmp[++i] = mv;
59241198Sbostic side = otherside[side];
59341198Sbostic }
59441198Sbostic else if (c == 0 && i > 0)
59541198Sbostic {
59641198Sbostic entry = (struct BookEntry *)malloc(sizeof(struct BookEntry));
59741198Sbostic mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short));
59841198Sbostic entry->mv = mp;
59941198Sbostic entry->next = Book;
60041198Sbostic Book = entry;
60141198Sbostic for (j = 1; j <= i; j++) *(mp++) = tmp[j];
60241198Sbostic *mp = 0;
60341198Sbostic i = 0; side = white;
60441198Sbostic }
60541198Sbostic fclose(fd);
60641198Sbostic }
60741199Sbostic else
60841199Sbostic {
60941199Sbostic fprintf(stderr, "\nchess: can't read %s.\n", _PATH_CHESSBOOK);
61041199Sbostic exit(1);
61141199Sbostic }
61241198Sbostic }
61341198Sbostic
61441198Sbostic
parse(fd,mv,side)61541198Sbostic int parse(fd,mv,side)
61641198Sbostic FILE *fd;
61741198Sbostic unsigned short *mv;
61841198Sbostic short side;
61941198Sbostic {
62041198Sbostic int c,i,r1,r2,c1,c2;
62141198Sbostic char s[100];
62241198Sbostic while ((c = getc(fd)) == ' ');
62341198Sbostic i = 0; s[0] = c;
62441198Sbostic while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd);
62541198Sbostic s[++i] = '\0';
62641198Sbostic if (c == EOF) return(-1);
62741198Sbostic if (s[0] == '!' || i < 3)
62841198Sbostic {
62941198Sbostic while (c != '\n' && c != EOF) c = getc(fd);
63041198Sbostic return(0);
63141198Sbostic }
63241198Sbostic if (s[4] == 'o')
63341198Sbostic if (side == black) *mv = 0x3C3A; else *mv = 0x0402;
63441198Sbostic else if (s[0] == 'o')
63541198Sbostic if (side == black) *mv = 0x3C3E; else *mv = 0x0406;
63641198Sbostic else
63741198Sbostic {
63841198Sbostic c1 = s[0] - 'a'; r1 = s[1] - '1';
63941198Sbostic c2 = s[2] - 'a'; r2 = s[3] - '1';
64041198Sbostic *mv = (locn[r1][c1]<<8) + locn[r2][c2];
64141198Sbostic }
64241198Sbostic return(1);
64341198Sbostic }
64441198Sbostic
64541198Sbostic
GetGame()64641198Sbostic GetGame()
64741198Sbostic {
64841198Sbostic FILE *fd;
64941198Sbostic char fname[40];
65041198Sbostic int c;
65141198Sbostic short sq;
65241198Sbostic unsigned short m;
65341198Sbostic
65441198Sbostic ShowMessage("File name: ");
65541198Sbostic scanz("%s",fname);
65641198Sbostic if (fname[0] == '\0') strcpy(fname,"chess.000");
65741198Sbostic if ((fd = fopen(fname,"r")) != NULL)
65841198Sbostic {
65941198Sbostic fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
66041198Sbostic fscanf(fd,"%hd%hd%hd%hd",
66141198Sbostic &castld[white],&castld[black],
66241198Sbostic &kingmoved[white],&kingmoved[black]);
66341198Sbostic fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
66441198Sbostic fscanf(fd,"%ld%ld%hd%hd",
66541198Sbostic &TimeControl.clock[white],&TimeControl.clock[black],
66641198Sbostic &TimeControl.moves[white],&TimeControl.moves[black]);
66741198Sbostic for (sq = 0; sq < 64; sq++)
66841198Sbostic {
66941198Sbostic fscanf(fd,"%hd",&m);
67041198Sbostic board[sq] = (m >> 8); color[sq] = (m & 0xFF);
67141198Sbostic if (color[sq] == 0) color[sq] = neutral; else --color[sq];
67241198Sbostic }
67341198Sbostic GameCnt = -1; c = '?';
67441198Sbostic while (c != EOF)
67541198Sbostic {
67641198Sbostic ++GameCnt;
67741198Sbostic c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
67841198Sbostic &GameList[GameCnt].score,&GameList[GameCnt].depth,
67941198Sbostic &GameList[GameCnt].nodes,&GameList[GameCnt].time,
68041198Sbostic &GameList[GameCnt].piece,&GameList[GameCnt].color);
68141198Sbostic if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral;
68241198Sbostic else --GameList[GameCnt].color;
68341198Sbostic }
68441198Sbostic GameCnt--;
68541198Sbostic if (TimeControl.clock[white] > 0) TCflag = true;
68641198Sbostic computer--; opponent--;
68741198Sbostic }
68841198Sbostic fclose(fd);
68941198Sbostic InitializeStats();
69041198Sbostic UpdateDisplay(0,0,1,0);
69141198Sbostic Sdepth = 0;
69241198Sbostic }
69341198Sbostic
69441198Sbostic
SaveGame()69541198Sbostic SaveGame()
69641198Sbostic {
69741198Sbostic FILE *fd;
69841198Sbostic char fname[40];
69941198Sbostic short sq,i,c;
70041198Sbostic
70141198Sbostic ShowMessage("File name: ");
70241198Sbostic scanz("%s",fname);
70341198Sbostic
70441198Sbostic if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000");
70541198Sbostic fd = fopen(fname,"w");
70641198Sbostic fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50);
70741198Sbostic fprintf(fd,"%d %d %d %d\n",
70841198Sbostic castld[white],castld[black],kingmoved[white],kingmoved[black]);
70941198Sbostic fprintf(fd,"%d %d\n",TCflag,OperatorTime);
71041198Sbostic fprintf(fd,"%ld %ld %d %d\n",
71141198Sbostic TimeControl.clock[white],TimeControl.clock[black],
71241198Sbostic TimeControl.moves[white],TimeControl.moves[black]);
71341198Sbostic for (sq = 0; sq < 64; sq++)
71441198Sbostic {
71541198Sbostic if (color[sq] == neutral) c = 0; else c = color[sq]+1;
71641198Sbostic fprintf(fd,"%d\n",256*board[sq] + c);
71741198Sbostic }
71841198Sbostic for (i = 0; i <= GameCnt; i++)
71941198Sbostic {
72041198Sbostic if (GameList[i].color == neutral) c = 0;
72141198Sbostic else c = GameList[i].color + 1;
72241198Sbostic fprintf(fd,"%d %d %d %ld %d %d %d\n",
72341198Sbostic GameList[i].gmove,GameList[i].score,GameList[i].depth,
72441198Sbostic GameList[i].nodes,GameList[i].time,
72541198Sbostic GameList[i].piece,c);
72641198Sbostic }
72741198Sbostic fclose(fd);
72841198Sbostic }
72941198Sbostic
73041198Sbostic
ListGame()73141198Sbostic ListGame()
73241198Sbostic {
73341198Sbostic FILE *fd;
73441198Sbostic short i,f,t;
73541198Sbostic fd = fopen("chess.lst","w");
73641198Sbostic fprintf(fd,"\n");
73741198Sbostic fprintf(fd," score depth nodes time ");
73841198Sbostic fprintf(fd," score depth nodes time\n");
73941198Sbostic for (i = 0; i <= GameCnt; i++)
74041198Sbostic {
74141198Sbostic f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
74241198Sbostic algbr(f,t,false);
74341198Sbostic if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," ");
74441198Sbostic fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1,
74541198Sbostic GameList[i].score,GameList[i].depth,
74641198Sbostic GameList[i].nodes,GameList[i].time);
74741198Sbostic }
74841198Sbostic fprintf(fd,"\n\n");
74941198Sbostic fclose(fd);
75041198Sbostic }
75141198Sbostic
75241198Sbostic
Undo()75341198Sbostic Undo()
75441198Sbostic
75541198Sbostic /*
75641198Sbostic Undo the most recent half-move.
75741198Sbostic */
75841198Sbostic
75941198Sbostic {
76041198Sbostic short f,t;
76141198Sbostic f = GameList[GameCnt].gmove>>8;
76241198Sbostic t = GameList[GameCnt].gmove & 0xFF;
76341198Sbostic if (board[t] == king && distance(t,f) > 1)
76441198Sbostic castle(GameList[GameCnt].color,f,t,2);
76541198Sbostic else
76641198Sbostic {
76741198Sbostic board[f] = board[t]; color[f] = color[t];
76841198Sbostic board[t] = GameList[GameCnt].piece;
76941198Sbostic color[t] = GameList[GameCnt].color;
77041198Sbostic if (board[f] == king) --kingmoved[color[f]];
77141198Sbostic }
77241198Sbostic if (TCflag) ++TimeControl.moves[color[f]];
77341198Sbostic GameCnt--; mate = false; Sdepth = 0;
77441198Sbostic UpdateDisplay(0,0,1,0);
77541198Sbostic InitializeStats();
77641198Sbostic }
77741198Sbostic
77841198Sbostic
ShowMessage(s)77941198Sbostic ShowMessage(s)
78041198Sbostic char *s;
78141198Sbostic {
78241198Sbostic gotoXY(50,24); printz("%s",s); ClrEoln();
78341198Sbostic }
78441198Sbostic
ClearMessage()78541198Sbostic ClearMessage()
78641198Sbostic {
78741198Sbostic gotoXY(50,24); ClrEoln();
78841198Sbostic }
78941198Sbostic
ShowSidetomove()79041198Sbostic ShowSidetomove()
79141198Sbostic {
79241198Sbostic gotoXY(50,14);
79341198Sbostic if (player == white) printz("%2d: WHITE",1+(GameCnt+1)/2);
79441198Sbostic else printz("%2d: BLACK",1+(GameCnt+1)/2);
79541198Sbostic ClrEoln();
79641198Sbostic }
79741198Sbostic
PromptForMove()79841198Sbostic PromptForMove()
79941198Sbostic {
80041198Sbostic gotoXY(50,19); printz("Your move is? "); ClrEoln();
80141198Sbostic }
80241198Sbostic
ShowCurrentMove(pnt,f,t)80341198Sbostic ShowCurrentMove(pnt,f,t)
80441198Sbostic short pnt,f,t;
80541198Sbostic {
80641198Sbostic algbr(f,t,false);
80741198Sbostic gotoXY(50,7); printz("(%2d) %4s",pnt,mvstr1);
80841198Sbostic }
80941198Sbostic
ChangeAlphaWindow()81041198Sbostic ChangeAlphaWindow()
81141198Sbostic {
81241198Sbostic ShowMessage("window: ");
81341198Sbostic scanz("%hd",&Awindow);
81441198Sbostic }
81541198Sbostic
ChangeBetaWindow()81641198Sbostic ChangeBetaWindow()
81741198Sbostic {
81841198Sbostic ShowMessage("window: ");
81941198Sbostic scanz("%hd",&Bwindow);
82041198Sbostic }
82141198Sbostic
GiveHint()82241198Sbostic GiveHint()
82341198Sbostic {
82441198Sbostic char s[40];
82541198Sbostic algbr((short)(hint>>8),(short)(hint & 0xFF),false);
82641198Sbostic strcpy(s,"try ");
82741198Sbostic strcat(s,mvstr1);
82841198Sbostic ShowMessage(s);
82941198Sbostic }
83041198Sbostic
ChangeSearchDepth()83141198Sbostic ChangeSearchDepth()
83241198Sbostic {
83341198Sbostic ShowMessage("depth= ");
83441198Sbostic scanz("%hd",&MaxSearchDepth);
83541198Sbostic }
83641198Sbostic
SetContempt()83741198Sbostic SetContempt()
83841198Sbostic {
83941198Sbostic ShowMessage("contempt= ");
84041198Sbostic scanz("%hd",&contempt);
84141198Sbostic }
84241198Sbostic
ChangeXwindow()84341198Sbostic ChangeXwindow()
84441198Sbostic {
84541198Sbostic ShowMessage("xwndw= ");
84641198Sbostic scanz("%hd",&xwndw);
84741198Sbostic }
84841198Sbostic
84941198Sbostic
SelectLevel()85041198Sbostic SelectLevel()
85141198Sbostic {
85241198Sbostic ClrScreen();
85341198Sbostic gotoXY(32,2); printz("CHESS");
85441198Sbostic gotoXY(20,4); printz(" 1. 60 moves in 5 minutes");
85541198Sbostic gotoXY(20,5); printz(" 2. 60 moves in 15 minutes");
85641198Sbostic gotoXY(20,6); printz(" 3. 60 moves in 30 minutes");
85741198Sbostic gotoXY(20,7); printz(" 4. 40 moves in 30 minutes");
85841198Sbostic gotoXY(20,8); printz(" 5. 40 moves in 60 minutes");
85941198Sbostic gotoXY(20,9); printz(" 6. 40 moves in 120 minutes");
86041198Sbostic gotoXY(20,10); printz(" 7. 40 moves in 240 minutes");
86141198Sbostic gotoXY(20,11); printz(" 8. 1 move in 15 minutes");
86241198Sbostic gotoXY(20,12); printz(" 9. 1 move in 60 minutes");
86341198Sbostic gotoXY(20,13); printz("10. 1 move in 600 minutes");
86441198Sbostic
86541198Sbostic OperatorTime = 0; TCmoves = 60; TCminutes = 5;
86641198Sbostic
86741198Sbostic gotoXY(20,17); printz("Enter Level: ");
86841198Sbostic refresh();
86941198Sbostic scanz("%ld",&Level);
87041198Sbostic switch (Level)
87141198Sbostic {
87241198Sbostic case 1 : TCmoves = 60; TCminutes = 5; break;
87341198Sbostic case 2 : TCmoves = 60; TCminutes = 15; break;
87441198Sbostic case 3 : TCmoves = 60; TCminutes = 30; break;
87541198Sbostic case 4 : TCmoves = 40; TCminutes = 30; break;
87641198Sbostic case 5 : TCmoves = 40; TCminutes = 60; break;
87741198Sbostic case 6 : TCmoves = 40; TCminutes = 120; break;
87841198Sbostic case 7 : TCmoves = 40; TCminutes = 240; break;
87941198Sbostic case 8 : TCmoves = 1; TCminutes = 15; break;
88041198Sbostic case 9 : TCmoves = 1; TCminutes = 60; break;
88141198Sbostic case 10 : TCmoves = 1; TCminutes = 600; break;
88241198Sbostic }
88341198Sbostic
88441198Sbostic TCflag = (TCmoves > 1);
88541198Sbostic SetTimeControl();
88641198Sbostic ClrScreen();
88741198Sbostic UpdateDisplay(0,0,1,0);
88841198Sbostic }
88941198Sbostic
89041198Sbostic
ShowPostnValues()89141198Sbostic ShowPostnValues()
89241198Sbostic {
89341198Sbostic short i,r,c;
89441198Sbostic ExaminePosition();
89541198Sbostic for (i = 0; i < 64; i++)
89641198Sbostic {
89741198Sbostic if (reverse) r = 7-row[i]; else r = row[i];
89841198Sbostic if (reverse) c = 7-column[i]; else c = column[i];
89941198Sbostic gotoXY(4+5*c,5+2*(7-r));
90041198Sbostic c1 = color[i]; c2 = otherside[c1];
90141198Sbostic PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];
90241198Sbostic atk1 = atak[c1]; atk2 = atak[c2];
90341198Sbostic if (color[i] == neutral) printz(" ");
90441198Sbostic else printz("%3d ",SqValue(i,opponent));
90541198Sbostic }
90641198Sbostic ScorePosition(opponent,&i);
90741198Sbostic gotoXY(50,24);
90841198Sbostic printz("Score= %d",i); ClrEoln();
90941198Sbostic }
91041198Sbostic
91141198Sbostic
DoDebug()91241198Sbostic DoDebug()
91341198Sbostic {
91441198Sbostic short k,p,i,r,c,tp,tc;
91541198Sbostic char s[40];
91641198Sbostic ExaminePosition();
91741198Sbostic ShowMessage("Enter piece: ");
91841198Sbostic scanz("%s",s);
91941198Sbostic if (s[0] == 'w') k = white; else k = black;
92041198Sbostic if (s[1] == 'p') p = pawn;
92141198Sbostic else if (s[1] == 'n') p = knight;
92241198Sbostic else if (s[1] == 'b') p = bishop;
92341198Sbostic else if (s[1] == 'r') p = rook;
92441198Sbostic else if (s[1] == 'q') p = queen;
92541198Sbostic else if (s[1] == 'k') p = king;
92641198Sbostic else p = no_piece;
92741198Sbostic for (i = 0; i < 64; i++)
92841198Sbostic {
92941198Sbostic if (reverse) r = 7-row[i]; else r = row[i];
93041198Sbostic if (reverse) c = 7-column[i]; else c = column[i];
93141198Sbostic gotoXY(4+5*c,5+2*(7-r));
93241198Sbostic tp = board[i]; tc = color[i];
93341198Sbostic board[i] = p; color[i] = k;
93441198Sbostic c1 = k; c2 = otherside[c1];
93541198Sbostic PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];
93641198Sbostic atk1 = atak[c1]; atk2 = atak[c2];
93741198Sbostic printz("%3d ",SqValue(i,opponent));
93841198Sbostic board[i] = tp; color[i] = tc;
93941198Sbostic }
94041198Sbostic ScorePosition(opponent,&i);
94141198Sbostic gotoXY(50,24);
94241198Sbostic printz("Score= %d",i); ClrEoln();
94341198Sbostic }
944