xref: /csrg-svn/games/chess/uxdsp.c (revision 41199)
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