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