1993-03-21 12:45:37 +03:00
|
|
|
/*
|
|
|
|
UNIX & MSDOS NON-DISPLAY, AND CHESSTOOL interface for Chess
|
|
|
|
|
|
|
|
Revision: 4-25-88
|
|
|
|
|
|
|
|
Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
|
|
|
|
Copyright (c) 1988 John Stanback
|
|
|
|
|
|
|
|
This file is part of CHESS.
|
|
|
|
|
|
|
|
CHESS is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY. No author or distributor
|
|
|
|
accepts responsibility to anyone for the consequences of using it
|
|
|
|
or for whether it serves any particular purpose or works at all,
|
|
|
|
unless he says so in writing. Refer to the CHESS General Public
|
|
|
|
License for full details.
|
|
|
|
|
|
|
|
Everyone is granted permission to copy, modify and redistribute
|
|
|
|
CHESS, but only under the conditions described in the
|
|
|
|
CHESS General Public License. A copy of this license is
|
|
|
|
supposed to have been given to you along with CHESS so you
|
|
|
|
can know your rights and responsibilities. It should be in a
|
|
|
|
file named COPYING. Among other things, the copyright notice
|
|
|
|
and this notice must be preserved on all copies.
|
|
|
|
*/
|
|
|
|
|
1993-08-02 21:18:41 +04:00
|
|
|
#ifndef lint
|
|
|
|
static char rcsid[] = "$Id: nondsp.c,v 1.2 1993/08/02 17:21:22 mycroft Exp $";
|
|
|
|
#endif /* not lint */
|
1993-03-21 12:45:37 +03:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#ifdef MSDOS
|
|
|
|
#include <dos.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
#else
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/times.h>
|
|
|
|
#include <sys/file.h>
|
|
|
|
struct tms tmbuf1,tmbuf2;
|
|
|
|
int TerminateSearch(),Die();
|
|
|
|
#endif MSDOS
|
|
|
|
|
|
|
|
#include "gnuchess.h"
|
|
|
|
#ifdef NEWMOVE
|
|
|
|
#include "move.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define printz printf
|
|
|
|
#define scanz scanf
|
|
|
|
int mycnt1,mycnt2;
|
|
|
|
|
|
|
|
|
|
|
|
Initialize()
|
|
|
|
{
|
|
|
|
mycnt1 = mycnt2 = 0;
|
|
|
|
#ifndef MSDOS
|
|
|
|
#endif
|
|
|
|
#ifdef CHESSTOOL
|
|
|
|
setlinebuf(stdout);
|
|
|
|
/*
|
|
|
|
setvbuf(stdout,NULL,_IOLBF,BUFSIZ);
|
|
|
|
*/
|
|
|
|
printf("Chess\n");
|
|
|
|
if (Level == 0 && !TCflag) Level = 15;
|
|
|
|
#endif CHESSTOOL
|
|
|
|
}
|
|
|
|
|
|
|
|
ExitChess()
|
|
|
|
{
|
|
|
|
ListGame();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef MSDOS
|
|
|
|
Die()
|
|
|
|
{
|
|
|
|
char s[80];
|
|
|
|
printz("Abort? ");
|
|
|
|
scanz("%s",s);
|
|
|
|
if (strcmp(s,"yes") == 0) ExitChess();
|
|
|
|
}
|
|
|
|
|
|
|
|
TerminateSearch()
|
|
|
|
{
|
|
|
|
timeout = true;
|
|
|
|
bothsides = false;
|
|
|
|
}
|
|
|
|
#endif MSDOS
|
|
|
|
|
|
|
|
|
|
|
|
InputCommand()
|
|
|
|
|
|
|
|
/*
|
|
|
|
Process the users command. If easy mode is OFF (the computer is
|
|
|
|
thinking on opponents time) and the program is out of book, then make
|
|
|
|
the 'hint' move on the board and call SelectMove() to find a response.
|
|
|
|
The user terminates the search by entering ^C (quit siqnal) before
|
|
|
|
entering a command. If the opponent does not make the hint move, then
|
|
|
|
set Sdepth to zero.
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
short ok,tmp;
|
|
|
|
long cnt,rate,t1,t2;
|
|
|
|
unsigned short mv;
|
|
|
|
char s[80];
|
|
|
|
|
|
|
|
ok = quit = false;
|
|
|
|
player = opponent;
|
|
|
|
ft = 0;
|
|
|
|
if (hint > 0 && !easy && Book == NULL)
|
|
|
|
{
|
|
|
|
fflush(stdout);
|
|
|
|
time0 = time((long *)0);
|
|
|
|
algbr(hint>>8,hint & 0xFF,false);
|
|
|
|
strcpy(s,mvstr1);
|
|
|
|
tmp = epsquare;
|
|
|
|
if (VerifyMove(s,1,&mv))
|
|
|
|
{
|
|
|
|
SelectMove(computer,2);
|
|
|
|
VerifyMove(mvstr1,2,&mv);
|
|
|
|
if (Sdepth > 0) Sdepth--;
|
|
|
|
}
|
|
|
|
ft = time((long *)0) - time0;
|
|
|
|
epsquare = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef MSDOS
|
|
|
|
#endif
|
|
|
|
while (!(ok || quit))
|
|
|
|
{
|
|
|
|
PromptForMove();
|
|
|
|
i = scanz("%s",s);
|
|
|
|
if (i == EOF || s[0] == 0) ExitChess();
|
|
|
|
player = opponent;
|
|
|
|
ok = VerifyMove(s,0,&mv);
|
|
|
|
if (ok && mv != hint)
|
|
|
|
{
|
|
|
|
Sdepth = 0;
|
|
|
|
ft = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(s,"bd") == 0)
|
|
|
|
{
|
|
|
|
ClrScreen();
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
}
|
|
|
|
if (strcmp(s,"quit") == 0) quit = true;
|
|
|
|
if (strcmp(s,"post") == 0) post = !post;
|
|
|
|
if (strcmp(s,"set") == 0) EditBoard();
|
|
|
|
if (strcmp(s,"go") == 0) ok = true;
|
|
|
|
if (strcmp(s,"help") == 0) help();
|
|
|
|
if (strcmp(s,"force") == 0) force = !force;
|
|
|
|
if (strcmp(s,"book") == 0) Book = NULL;
|
|
|
|
if (strcmp(s,"new") == 0) NewGame();
|
|
|
|
if (strcmp(s,"list") == 0) ListGame();
|
|
|
|
if (strcmp(s,"level") == 0) SelectLevel();
|
|
|
|
if (strcmp(s,"hash") == 0) hashflag = !hashflag;
|
|
|
|
if (strcmp(s,"beep") == 0) beep = !beep;
|
|
|
|
if (strcmp(s,"Awindow") == 0) ChangeAlphaWindow();
|
|
|
|
if (strcmp(s,"Bwindow") == 0) ChangeBetaWindow();
|
|
|
|
if (strcmp(s,"rcptr") == 0) rcptr = !rcptr;
|
|
|
|
if (strcmp(s,"hint") == 0) GiveHint();
|
|
|
|
if (strcmp(s,"zero") == 0) ZeroTTable();
|
|
|
|
if (strcmp(s,"both") == 0)
|
|
|
|
{
|
|
|
|
bothsides = !bothsides;
|
|
|
|
Sdepth = 0;
|
|
|
|
SelectMove(opponent,1);
|
|
|
|
ok = true;
|
|
|
|
}
|
|
|
|
if (strcmp(s,"reverse") == 0)
|
|
|
|
{
|
|
|
|
reverse = !reverse;
|
|
|
|
ClrScreen();
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
}
|
|
|
|
if (strcmp(s,"switch") == 0)
|
|
|
|
{
|
|
|
|
computer = otherside[computer];
|
|
|
|
opponent = otherside[opponent];
|
|
|
|
force = false;
|
|
|
|
Sdepth = 0;
|
|
|
|
ok = true;
|
|
|
|
}
|
|
|
|
if (strcmp(s,"white") == 0)
|
|
|
|
{
|
|
|
|
computer = white; opponent = black;
|
|
|
|
ok = true; force = false;
|
|
|
|
Sdepth = 0;
|
|
|
|
}
|
|
|
|
if (strcmp(s,"black") == 0)
|
|
|
|
{
|
|
|
|
computer = black; opponent = white;
|
|
|
|
ok = true; force = false;
|
|
|
|
Sdepth = 0;
|
|
|
|
}
|
|
|
|
if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo();
|
|
|
|
if (strcmp(s,"remove") == 0 && GameCnt >= 1)
|
|
|
|
{
|
|
|
|
Undo(); Undo();
|
|
|
|
}
|
|
|
|
if (strcmp(s,"get") == 0) GetGame();
|
|
|
|
if (strcmp(s,"save") == 0) SaveGame();
|
|
|
|
if (strcmp(s,"depth") == 0) ChangeSearchDepth();
|
|
|
|
if (strcmp(s,"random") == 0) dither = 6;
|
|
|
|
if (strcmp(s,"easy") == 0) easy = !easy;
|
|
|
|
if (strcmp(s,"contempt") == 0) SetContempt();
|
|
|
|
if (strcmp(s,"xwndw") == 0) ChangeXwindow();
|
|
|
|
if (strcmp(s,"test") == 0)
|
|
|
|
{
|
|
|
|
t1 = time(0);
|
|
|
|
cnt = 0;
|
|
|
|
for (i = 0; i < 10000; i++)
|
|
|
|
{
|
|
|
|
MoveList(opponent,2);
|
|
|
|
cnt += TrPnt[3] - TrPnt[2];
|
|
|
|
}
|
|
|
|
t2 = time(0);
|
|
|
|
rate = cnt / (t2-t1);
|
|
|
|
printz("cnt= %ld rate= %ld\n",cnt,rate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ElapsedTime(1);
|
|
|
|
if (force)
|
|
|
|
{
|
|
|
|
computer = opponent; opponent = otherside[computer];
|
|
|
|
}
|
|
|
|
#ifndef MSDOS
|
|
|
|
(void) times(&tmbuf1);
|
|
|
|
#ifdef CHESSTOOL
|
|
|
|
printf("%d. %s\n",++mycnt2,s);
|
|
|
|
#endif CHESSTOOL
|
|
|
|
#endif MSDOS
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
help()
|
|
|
|
{
|
|
|
|
ClrScreen();
|
|
|
|
printz("CHESS command summary\n");
|
|
|
|
printz("g1f3 move from g1 to f3\n");
|
|
|
|
printz("nf3 move knight to f3\n");
|
|
|
|
printz("o-o castle king side\n");
|
|
|
|
printz("o-o-o castle queen side\n");
|
|
|
|
printz("set edit board\n");
|
|
|
|
printz("switch sides with computer\n");
|
|
|
|
printz("white computer plays white\n");
|
|
|
|
printz("black computer plays black\n");
|
|
|
|
printz("reverse board display\n");
|
|
|
|
printz("both computer match\n");
|
|
|
|
printz("random randomize play\n");
|
|
|
|
printz("undo undo last move\n");
|
|
|
|
printz("time change level\n");
|
|
|
|
printz("depth set search depth\n");
|
|
|
|
printz("post principle variation\n");
|
|
|
|
printz("hint suggest a move\n");
|
|
|
|
printz("bd redraw board\n");
|
|
|
|
printz("clock set time control\n");
|
|
|
|
printz("force enter game moves\n");
|
|
|
|
printz("list game to chess.lst\n");
|
|
|
|
printz("save game to file\n");
|
|
|
|
printz("get game from file\n");
|
|
|
|
printz("new start new game\n");
|
|
|
|
printz("quit exit CHESS\n");
|
|
|
|
printz("Computer: ");
|
|
|
|
if (computer == white) printz("WHITE\n"); else printz("BLACK\n");
|
|
|
|
printz("Opponent: ");
|
|
|
|
if (opponent == white) printz("WHITE\n"); else printz("BLACK\n");
|
|
|
|
printz("Response time: %ld",Level," sec.\n");
|
|
|
|
printz("Easy mode: ");
|
|
|
|
if (easy) printz("ON\n"); else printz("OFF\n");
|
|
|
|
printz("Depth: %d\n",MaxSearchDepth);
|
|
|
|
printz("Random: ");
|
|
|
|
if (dither) printz("ON\n"); else printz("OFF\n");
|
|
|
|
printz("Transposition table: ");
|
|
|
|
if (hashflag) printz("ON\n"); else printz("OFF\n");
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditBoard()
|
|
|
|
|
|
|
|
/*
|
|
|
|
Set up a board position. Pieces are entered by typing the piece
|
|
|
|
followed by the location. For example, Nf3 will place a knight on
|
|
|
|
square f3.
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
short a,r,c,sq;
|
|
|
|
char s[80];
|
|
|
|
|
|
|
|
ClrScreen();
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
printz(". exit to main\n");
|
|
|
|
printz("# clear board\n");
|
|
|
|
printz("enter piece & location: \n");
|
|
|
|
|
|
|
|
a = white;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
scanz("%s",s);
|
|
|
|
if (s[0] == '#')
|
|
|
|
{
|
|
|
|
for (sq = 0; sq < 64; sq++)
|
|
|
|
{
|
|
|
|
board[sq] = no_piece; color[sq] = neutral;
|
|
|
|
}
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
}
|
|
|
|
if (s[0] == 'c' || s[0] == 'C') a = otherside[a];
|
|
|
|
c = s[1]-'a'; r = s[2]-'1';
|
|
|
|
if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
|
|
|
|
{
|
|
|
|
sq = locn[r][c];
|
|
|
|
color[sq] = a;
|
|
|
|
if (s[0] == 'p') board[sq] = pawn;
|
|
|
|
else if (s[0] == 'n') board[sq] = knight;
|
|
|
|
else if (s[0] == 'b') board[sq] = bishop;
|
|
|
|
else if (s[0] == 'r') board[sq] = rook;
|
|
|
|
else if (s[0] == 'q') board[sq] = queen;
|
|
|
|
else if (s[0] == 'k') board[sq] = king;
|
|
|
|
else { board[sq] = no_piece; color[sq] = neutral; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (s[0] != '.');
|
|
|
|
if (board[4] != king) kingmoved[white] = 10;
|
|
|
|
if (board[60] != king) kingmoved[black] = 10;
|
|
|
|
GameCnt = -1; Game50 = 0; Sdepth = 0;
|
|
|
|
InitializeStats();
|
|
|
|
ClrScreen();
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ShowDepth(ch)
|
|
|
|
char ch;
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ShowResults(score,bstline,ch)
|
|
|
|
short score;
|
|
|
|
unsigned short bstline[];
|
|
|
|
char ch;
|
|
|
|
{
|
|
|
|
#ifndef CHESSTOOL
|
|
|
|
register int i;
|
|
|
|
printz("%2d%c %5d %4ld %7ld ",Sdepth,ch,score,et,NodeCnt);
|
|
|
|
for (i = 1; bstline[i] > 0; i++)
|
|
|
|
{
|
|
|
|
algbr((short)(bstline[i] >> 8),(short)(bstline[i] & 0xFF),false);
|
|
|
|
if (i == 9 || i == 17) printz("\n ");
|
|
|
|
printz("%5s ",mvstr1);
|
|
|
|
}
|
|
|
|
printz("\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SearchStartStuff(side)
|
|
|
|
short side;
|
|
|
|
{
|
|
|
|
#ifndef MSDOS
|
|
|
|
#endif
|
|
|
|
#ifndef CHESSTOOL
|
|
|
|
printz("\nMove# %d Target= %ld Clock: %ld\n",
|
|
|
|
TCmoves-TimeControl.moves[side]+1,
|
|
|
|
ResponseTime,TimeControl.clock[side]);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OutputMove()
|
|
|
|
{
|
|
|
|
#ifdef CHESSTOOL
|
|
|
|
printz("%d. ... %s\n",++mycnt1,mvstr1);
|
|
|
|
if (root->flags & draw)
|
|
|
|
{
|
|
|
|
printz("Draw\n");
|
|
|
|
ListGame();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
if (root->score == -9999)
|
|
|
|
{
|
|
|
|
if (opponent == white) printz("White\n"); else printz("Black\n");
|
|
|
|
ListGame();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
if (root->score == 9998)
|
|
|
|
{
|
|
|
|
if (computer == white) printz("White\n"); else printz("Black\n");
|
|
|
|
ListGame();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
printz("Nodes= %ld Eval= %ld Hash= %ld Rate= %ld ",
|
|
|
|
NodeCnt,EvalNodes,HashCnt,evrate);
|
|
|
|
printz("CPU= %.2ld:%.2ld.%.2ld\n\n",
|
|
|
|
cputimer/6000,(cputimer % 6000)/100,cputimer % 100);
|
|
|
|
|
|
|
|
if (root->flags & epmask) UpdateDisplay(0,0,1,0);
|
|
|
|
else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask);
|
|
|
|
printz("My move is: %s\n\n",mvstr1);
|
|
|
|
if (beep) printz("%c",7);
|
|
|
|
|
|
|
|
if (root->flags & draw) printz("Draw game!\n");
|
|
|
|
else if (root->score == -9999) printz("opponent mates!\n");
|
|
|
|
else if (root->score == 9998) printz("computer mates!\n");
|
|
|
|
else if (root->score < -9000) printz("opponent will soon mate!\n");
|
|
|
|
else if (root->score > 9000) printz("computer will soon mate!\n");
|
|
|
|
#endif CHESSTOOL
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ElapsedTime(iop)
|
|
|
|
short iop;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Determine the time that has passed since the search was started. If
|
|
|
|
the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
|
|
|
|
timeout to true which will terminate the search.
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
et = time((long *)0) - time0;
|
|
|
|
if (et < 0) et = 0;
|
|
|
|
ETnodes += 50;
|
|
|
|
if (et > et0 || iop == 1)
|
|
|
|
{
|
|
|
|
if (et > ResponseTime+ExtraTime && Sdepth > 1) timeout = true;
|
|
|
|
et0 = et;
|
|
|
|
if (iop == 1)
|
|
|
|
{
|
|
|
|
time0 = time((long *)0); et0 = 0;
|
|
|
|
}
|
|
|
|
#ifdef MSDOS
|
|
|
|
cputimer = 100*et;
|
|
|
|
if (et > 0) evrate = NodeCnt/(et+ft); else evrate = 0;
|
|
|
|
if (kbhit() && Sdepth > 1)
|
|
|
|
{
|
|
|
|
timeout = true;
|
|
|
|
bothsides = false;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
(void) times(&tmbuf2);
|
|
|
|
cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ;
|
|
|
|
if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft);
|
|
|
|
else evrate = 0;
|
|
|
|
#endif MSDOS
|
|
|
|
ETnodes = NodeCnt + 50;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetTimeControl()
|
|
|
|
{
|
|
|
|
if (TCflag)
|
|
|
|
{
|
|
|
|
TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
|
|
|
|
TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TimeControl.moves[white] = TimeControl.moves[black] = 0;
|
|
|
|
TimeControl.clock[white] = TimeControl.clock[black] = 0;
|
|
|
|
Level = 60*(long)TCminutes;
|
|
|
|
}
|
|
|
|
et = 0;
|
|
|
|
ElapsedTime(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ClrScreen()
|
|
|
|
{
|
|
|
|
#ifndef CHESSTOOL
|
|
|
|
printz("\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UpdateDisplay(f,t,flag,iscastle)
|
|
|
|
short f,t,flag,iscastle;
|
|
|
|
{
|
|
|
|
#ifndef CHESSTOOL
|
|
|
|
short r,c,l;
|
|
|
|
if (flag)
|
|
|
|
{
|
|
|
|
printz("\n");
|
|
|
|
for (r = 7; r >= 0; r--)
|
|
|
|
{
|
|
|
|
for (c = 0; c <= 7; c++)
|
|
|
|
{
|
|
|
|
if (reverse) l = locn[7-r][7-c]; else l = locn[r][c];
|
|
|
|
if (color[l] == neutral) printz(" -");
|
|
|
|
else if (color[l] == white) printz(" %c",qxx[board[l]]);
|
|
|
|
else printz(" %c",pxx[board[l]]);
|
|
|
|
}
|
|
|
|
printz("\n");
|
|
|
|
}
|
|
|
|
printz("\n");
|
|
|
|
}
|
|
|
|
#endif CHESSTOOL
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GetOpenings()
|
|
|
|
|
|
|
|
/*
|
|
|
|
Read in the Opening Book file and parse the algebraic notation for a
|
|
|
|
move into an unsigned integer format indicating the from and to
|
|
|
|
square. Create a linked list of opening lines of play, with
|
|
|
|
entry->next pointing to the next line and entry->move pointing to a
|
|
|
|
chunk of memory containing the moves. More Opening lines of up to 256
|
|
|
|
half moves may be added to gnuchess.book.
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
int c,i,j,side;
|
|
|
|
char buffr[2048];
|
|
|
|
struct BookEntry *entry;
|
|
|
|
unsigned short mv,*mp,tmp[100];
|
|
|
|
|
|
|
|
if ((fd = fopen("gnuchess.book","r")) != NULL)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
setvbuf(fd,buffr,_IOFBF,2048);
|
|
|
|
*/
|
|
|
|
Book = NULL;
|
|
|
|
i = 0; side = white;
|
|
|
|
while ((c = parse(fd,&mv,side)) >= 0)
|
|
|
|
if (c == 1)
|
|
|
|
{
|
|
|
|
tmp[++i] = mv;
|
|
|
|
side = otherside[side];
|
|
|
|
}
|
|
|
|
else if (c == 0 && i > 0)
|
|
|
|
{
|
|
|
|
entry = (struct BookEntry *)malloc(sizeof(struct BookEntry));
|
|
|
|
mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short));
|
|
|
|
entry->mv = mp;
|
|
|
|
entry->next = Book;
|
|
|
|
Book = entry;
|
|
|
|
for (j = 1; j <= i; j++) *(mp++) = tmp[j];
|
|
|
|
*mp = 0;
|
|
|
|
i = 0; side = white;
|
|
|
|
}
|
|
|
|
fclose(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int parse(fd,mv,side)
|
|
|
|
FILE *fd;
|
|
|
|
unsigned short *mv;
|
|
|
|
short side;
|
|
|
|
{
|
|
|
|
int c,i,r1,r2,c1,c2;
|
|
|
|
char s[100];
|
|
|
|
while ((c = getc(fd)) == ' ');
|
|
|
|
i = 0; s[0] = c;
|
|
|
|
while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd);
|
|
|
|
s[++i] = '\0';
|
|
|
|
if (c == EOF) return(-1);
|
|
|
|
if (s[0] == '!' || i < 3)
|
|
|
|
{
|
|
|
|
while (c != '\n' && c != EOF) c = getc(fd);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
if (s[4] == 'o')
|
|
|
|
if (side == black) *mv = 0x3C3A; else *mv = 0x0402;
|
|
|
|
else if (s[0] == 'o')
|
|
|
|
if (side == black) *mv = 0x3C3E; else *mv = 0x0406;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
c1 = s[0] - 'a'; r1 = s[1] - '1';
|
|
|
|
c2 = s[2] - 'a'; r2 = s[3] - '1';
|
|
|
|
*mv = (locn[r1][c1]<<8) + locn[r2][c2];
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GetGame()
|
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
char fname[40];
|
|
|
|
int c;
|
|
|
|
short sq;
|
|
|
|
unsigned short m;
|
|
|
|
|
|
|
|
printz("Enter file name: ");
|
|
|
|
scanz("%s",fname);
|
|
|
|
if (fname[0] == '\0') strcpy(fname,"chess.000");
|
|
|
|
if ((fd = fopen(fname,"r")) != NULL)
|
|
|
|
{
|
|
|
|
fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
|
|
|
|
fscanf(fd,"%hd%hd%hd%hd",
|
|
|
|
&castld[white],&castld[black],
|
|
|
|
&kingmoved[white],&kingmoved[black]);
|
|
|
|
fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
|
|
|
|
fscanf(fd,"%ld%ld%hd%hd",
|
|
|
|
&TimeControl.clock[white],&TimeControl.clock[black],
|
|
|
|
&TimeControl.moves[white],&TimeControl.moves[black]);
|
|
|
|
for (sq = 0; sq < 64; sq++)
|
|
|
|
{
|
|
|
|
fscanf(fd,"%hd",&m);
|
|
|
|
board[sq] = (m >> 8); color[sq] = (m & 0xFF);
|
|
|
|
if (color[sq] == 0) color[sq] = neutral; else --color[sq];
|
|
|
|
}
|
|
|
|
GameCnt = -1; c = '?';
|
|
|
|
while (c != EOF)
|
|
|
|
{
|
|
|
|
++GameCnt;
|
|
|
|
c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
|
|
|
|
&GameList[GameCnt].score,&GameList[GameCnt].depth,
|
|
|
|
&GameList[GameCnt].nodes,&GameList[GameCnt].time,
|
|
|
|
&GameList[GameCnt].piece,&GameList[GameCnt].color);
|
|
|
|
if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral;
|
|
|
|
else --GameList[GameCnt].color;
|
|
|
|
}
|
|
|
|
GameCnt--;
|
|
|
|
if (TimeControl.clock[white] > 0) TCflag = true;
|
|
|
|
computer--; opponent--;
|
|
|
|
}
|
|
|
|
fclose(fd);
|
|
|
|
InitializeStats();
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
Sdepth = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SaveGame()
|
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
char fname[40];
|
|
|
|
short sq,i,c;
|
|
|
|
|
|
|
|
printz("Enter file name: ");
|
|
|
|
scanz("%s",fname);
|
|
|
|
|
|
|
|
if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000");
|
|
|
|
fd = fopen(fname,"w");
|
|
|
|
fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50);
|
|
|
|
fprintf(fd,"%d %d %d %d\n",
|
|
|
|
castld[white],castld[black],kingmoved[white],kingmoved[black]);
|
|
|
|
fprintf(fd,"%d %d\n",TCflag,OperatorTime);
|
|
|
|
fprintf(fd,"%ld %ld %d %d\n",
|
|
|
|
TimeControl.clock[white],TimeControl.clock[black],
|
|
|
|
TimeControl.moves[white],TimeControl.moves[black]);
|
|
|
|
for (sq = 0; sq < 64; sq++)
|
|
|
|
{
|
|
|
|
if (color[sq] == neutral) c = 0; else c = color[sq]+1;
|
|
|
|
fprintf(fd,"%d\n",256*board[sq] + c);
|
|
|
|
}
|
|
|
|
for (i = 0; i <= GameCnt; i++)
|
|
|
|
{
|
|
|
|
if (GameList[i].color == neutral) c = 0;
|
|
|
|
else c = GameList[i].color + 1;
|
|
|
|
fprintf(fd,"%d %d %d %ld %d %d %d\n",
|
|
|
|
GameList[i].gmove,GameList[i].score,GameList[i].depth,
|
|
|
|
GameList[i].nodes,GameList[i].time,
|
|
|
|
GameList[i].piece,c);
|
|
|
|
}
|
|
|
|
fclose(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ListGame()
|
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
short i,f,t;
|
|
|
|
fd = fopen("chess.lst","w");
|
|
|
|
fprintf(fd,"\n");
|
|
|
|
fprintf(fd," score depth nodes time ");
|
|
|
|
fprintf(fd," score depth nodes time\n");
|
|
|
|
for (i = 0; i <= GameCnt; i++)
|
|
|
|
{
|
|
|
|
f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
|
|
|
|
algbr(f,t,false);
|
|
|
|
if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," ");
|
|
|
|
fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1,
|
|
|
|
GameList[i].score,GameList[i].depth,
|
|
|
|
GameList[i].nodes,GameList[i].time);
|
|
|
|
}
|
|
|
|
fprintf(fd,"\n\n");
|
|
|
|
fclose(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Undo()
|
|
|
|
|
|
|
|
/*
|
|
|
|
Undo the most recent half-move.
|
|
|
|
*/
|
|
|
|
|
|
|
|
{
|
|
|
|
short f,t;
|
|
|
|
f = GameList[GameCnt].gmove>>8;
|
|
|
|
t = GameList[GameCnt].gmove & 0xFF;
|
|
|
|
if (board[t] == king && distance(t,f) > 1)
|
|
|
|
castle(GameList[GameCnt].color,f,t,2);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
board[f] = board[t]; color[f] = color[t];
|
|
|
|
board[t] = GameList[GameCnt].piece;
|
|
|
|
color[t] = GameList[GameCnt].color;
|
|
|
|
if (board[f] == king) --kingmoved[color[f]];
|
|
|
|
}
|
|
|
|
if (TCflag) ++TimeControl.moves[color[f]];
|
|
|
|
GameCnt--; mate = false; Sdepth = 0;
|
|
|
|
UpdateDisplay(0,0,1,0);
|
|
|
|
InitializeStats();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ShowMessage(s)
|
|
|
|
char *s;
|
|
|
|
{
|
|
|
|
#ifndef CHESSTOOL
|
|
|
|
printz("%s\n");
|
|
|
|
#endif CHESSTOOL
|
|
|
|
}
|
|
|
|
|
|
|
|
ShowSidetomove()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
PromptForMove()
|
|
|
|
{
|
|
|
|
#ifndef CHESSTOOL
|
|
|
|
printz("\nYour move is? ");
|
|
|
|
#endif CHESSTOOL
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ShowCurrentMove(pnt,f,t)
|
|
|
|
short pnt,f,t;
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ChangeAlphaWindow()
|
|
|
|
{
|
|
|
|
printz("window: ");
|
|
|
|
scanz("%hd",&Awindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
ChangeBetaWindow()
|
|
|
|
{
|
|
|
|
printz("window: ");
|
|
|
|
scanz("%hd",&Bwindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
GiveHint()
|
|
|
|
{
|
|
|
|
algbr((short)(hint>>8),(short)(hint & 0xFF),false);
|
|
|
|
printz("try %s\n",mvstr1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SelectLevel()
|
|
|
|
{
|
|
|
|
OperatorTime = 30000;
|
|
|
|
printz("Enter #moves #minutes: ");
|
|
|
|
scanz("%hd %hd",&TCmoves,&TCminutes);
|
|
|
|
printz("Operator time= ");
|
|
|
|
scanz("%hd",&OperatorTime);
|
|
|
|
TCflag = (TCmoves > 1);
|
|
|
|
SetTimeControl();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ChangeSearchDepth()
|
|
|
|
{
|
|
|
|
printz("depth= ");
|
|
|
|
scanz("%hd",&MaxSearchDepth);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetContempt()
|
|
|
|
{
|
|
|
|
printz("contempt= ");
|
|
|
|
scanz("%hd",&contempt);
|
|
|
|
}
|
|
|
|
|
|
|
|
ChangeXwindow()
|
|
|
|
{
|
|
|
|
printz("xwndw= ");
|
|
|
|
scanz("%hd",&xwndw);
|
|
|
|
}
|