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