home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Select: Games 3
/
cd.iso
/
os2
/
pmgnuchs
/
dsp.c
< prev
next >
Wrap
Text File
|
1994-04-19
|
16KB
|
647 lines
//
// Copyright (C) 1986, 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
// Copyright (c) 1988, 1989, 1990 John Stanback
//
// Project: OS/2 PM Port of GNU CHESS 4.0 pl65 (PmGnuChs)
//
// Version: 1994-4-17
//
// Module: Misc GNU Logic (Dsp.c)
//
// Porter: Ported to Windows 3.0 by Darly Baker
//
// Porter: Ported to OS/2 1.2+ by Kent Cedola
//
// Porter: Ported to OS/2 2.1+ by Yibing Fan
//
// System: OS/2 2.1 using emx 0.8h
//
// Remarks: This code is combination of Kent's OS/2 1.2 porting and
// original code from GNU CHESS 4.0 pl65.
//
// License:
//
// 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.
//
#define INCL_DOS
#define INCL_PM
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "PmChess.h"
#include "GnuChess.h"
#include "Defs.h"
#include "Resource.h"
#include "ataks.h"
int mycntl1, mycntl2;
char mvstr[4][6];
char *InPtr;
long evrate, Level;
int PositionFlag = 0;
#define pxx " PNBRQK"
#define qxx " pnbrqk"
void TerminateSearch (int), Die (int);
void
Initialize (void)
{
mycntl1 = mycntl2 = 0;
}
void
ExitChess (void)
{
}
void
Die (int Sig)
{
}
void
TerminateSearch (int Sig)
{
flag.timeout = true;
flag.bothsides = false;
}
void
algbr (short int f, short int t, short int flag)
/*
Generate move strings in different formats.
*/
{
int m3p;
if (f != t)
{
/* algebraic notation */
mvstr[0][0] = (char) ('a'+column (f));
mvstr[0][1] = (char) ('1'+row (f));
mvstr[0][2] = (char) ('a'+column (t));
mvstr[0][3] = (char) ('1'+row (t));
mvstr[0][4] = mvstr[3][0] = '\0';
if ((mvstr[1][0] = pxx[board[f]]) == 'P')
{
if (mvstr[0][0] == mvstr[0][2]) /* pawn did not eat */
{
mvstr[2][0] = mvstr[1][0] = mvstr[0][2]; /* to column */
mvstr[2][1] = mvstr[1][1] = mvstr[0][3]; /* to row */
m3p = 2;
}
else
/* pawn ate */
{
mvstr[2][0] = mvstr[1][0] = mvstr[0][0]; /* from column */
mvstr[2][1] = mvstr[1][1] = mvstr[0][2]; /* to column */
mvstr[2][2] = mvstr[0][3];
m3p = 3; /* to row */
}
mvstr[2][m3p] = mvstr[1][2] = '\0';
if (flag & promote)
{
mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
}
}
else
/* not a pawn */
{
mvstr[2][0] = mvstr[1][0];
mvstr[2][1] = mvstr[0][1];
mvstr[2][2] = mvstr[1][1] = mvstr[0][2]; /* to column */
mvstr[2][3] = mvstr[1][2] = mvstr[0][3]; /* to row */
mvstr[2][4] = mvstr[1][3] = '\0';
strcpy (mvstr[3], mvstr[2]);
mvstr[3][1] = mvstr[0][0];
if (flag & cstlmask)
{
if (t > f)
{
strcpy (mvstr[1], "o-o");
strcpy (mvstr[2], "O-O");
}
else
{
strcpy (mvstr[1], "o-o-o");
strcpy (mvstr[2], "O-O-O");
}
}
}
}
else
mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
}
int
VerifyMove (HWND hWnd, char *s, short int iop, short unsigned int *mv)
/*
Compare the string 's' to the list of legal moves available for the
opponent. If a match is found, make the move on the board.
*/
{
static short pnt, tempb, tempc, tempsf, tempst, cnt;
static struct leaf xnode;
struct leaf *node;
*mv = 0;
if (iop == 2)
{
UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
return (false);
}
cnt = 0;
MoveList (opponent, 2);
pnt = TrPnt[2];
while (pnt < TrPnt[3])
{
node = &Tree[pnt++];
algbr (node->f, node->t, (short) node->flags);
if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
{
cnt++;
xnode = *node;
}
}
if (cnt == 1)
{
MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
if (SqAtakd (PieceList[opponent][0], computer))
{
UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
SMessageBox (hWnd, IDS_ILLEGALMOVE, IDS_CHESS);
return (false);
}
else
{
if (iop == 1)
return (true);
UpdateDisplay (hWnd, xnode.f, xnode.t, 0, (short) xnode.flags);
if ((board[xnode.t] == pawn)
|| (xnode.flags & capture)
|| (xnode.flags & cstlmask))
{
Game50 = GameCnt;
ZeroRPT ();
}
GameList[GameCnt].depth = GameList[GameCnt].score = 0;
GameList[GameCnt].nodes = 0;
ElapsedTime (1);
GameList[GameCnt].time = (short) et;
TimeControl.clock[opponent] -= et;
--TimeControl.moves[opponent];
*mv = (xnode.f << 8) | xnode.t;
algbr (xnode.f, xnode.t, false);
return (true);
}
}
if (cnt > 1) SMessageBox (hWnd, IDS_AMBIGUOUSMOVE, IDS_CHESS);
return (false);
}
void ElapsedTime (short int 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. iop = 0 calculate et bump ETnodes
* iop = 1 calculate et set timeout if time exceeded, calculate et
*/
{
// if ( _read_kbd (0,0,0) != -1)
// {
// if (!flag.timeout)
// flag.back = true;
// flag.bothsides = false;
// }
et = (time ((long *) 0) - time0) * 100;
ETnodes = NodeCnt + ZNODES;
if (et < 0)
et = 0;
if (iop == 1)
{
if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
flag.timeout = true;
ETnodes = NodeCnt + ZNODES;
time0 = time ((long *) 0);
}
if (et > 0)
evrate = NodeCnt * 100 / (et + ft);
else
evrate = 0;
// UpdateClocks ();
}
void
SetTimeControl (void)
{
if (TCflag)
{
TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
TimeControl.clock[white] = TimeControl.clock[black] = 6000 * (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);
}
void
GetGame (HWND hWnd, char *fname)
{
FILE *fd;
char *p;
int c, i, j;
int eps = -1;
short sq;
if ((fd = fopen (fname, "r")) != NULL)
{
NewGame (hWnd);
fgets (fname, 256, fd);
computer = opponent = white;
InPtr = fname;
skip ();
if (*InPtr == 'c')
computer = black;
else
opponent = black;
skip ();
skip ();
skip ();
Game50 = atoi (InPtr);
skip();
skip();
eps = atoi(InPtr);
fgets (fname, 256, fd);
InPtr = &fname[14];
castld[white] = ((*InPtr == CP[214][0]) ? true : false);
skip ();
skip ();
castld[black] = ((*InPtr == CP[214][0]) ? true : false);
fgets (fname, 256, fd);
InPtr = &fname[11];
skipb ();
TCflag = atoi (InPtr);
skip ();
InPtr += 14;
skipb ();
OperatorTime = atoi (InPtr);
fgets (fname, 256, fd);
InPtr = &fname[11];
skipb ();
TimeControl.clock[white] = atol (InPtr);
skip ();
skip ();
TimeControl.moves[white] = atoi (InPtr);
fgets (fname, 256, fd);
InPtr = &fname[11];
skipb ();
TimeControl.clock[black] = atol (InPtr);
skip ();
skip ();
TimeControl.moves[black] = atoi (InPtr);
fgets (fname, 256, fd);
for (i = 7; i > -1; i--)
{
fgets (fname, 256, fd);
p = &fname[2];
InPtr = &fname[11];
skipb ();
for (j = 0; j < 8; j++)
{
sq = i * 8 + j;
if (*p == '.')
{
board[sq] = no_piece;
color[sq] = neutral;
}
else
{
for (c = 0; c < 8; c++)
{
if (*p == pxx[c])
{
board[sq] = c;
color[sq] = black;
}
}
for (c = 0; c < 8; c++)
{
if (*p == qxx[c])
{
board[sq] = c;
color[sq] = white;
}
}
}
p++;
Mvboard[sq] = atoi (InPtr);
skip ();
}
}
GameCnt = 0;
flag.regularstart = true;
Book = BOOKFAIL;
fgets (fname, 256, fd);
fgets (fname, 256, fd);
fgets (fname, 256, fd);
while (fgets (fname, 256, fd))
{
struct GameRec *g;
int side = computer;
side = side ^ 1;
++GameCnt;
InPtr = fname;
skipb ();
g = &GameList[GameCnt];
g->gmove = parser (InPtr, side);
skip ();
g->score = atoi (InPtr);
skip ();
g->depth = atoi (InPtr);
skip ();
g->nodes = atol (InPtr);
skip ();
g->time = atol (InPtr);
skip ();
g->flags = c = atoi (InPtr);
skip ();
g->hashkey = strtol (InPtr, (char **) NULL, 16);
skip ();
g->hashbd = strtol (InPtr, (char **) NULL, 16);
skip ();
g->epssq = atoi(InPtr);
g->piece = no_piece;
g->color = neutral;
if (c & (capture | cstlmask))
{
if (c & capture)
{
skip ();
for (c = 0; c < 8; c++)
if (pxx[c] == *InPtr)
break;
g->piece = c;
}
skip ();
g->color = ((*InPtr == CP[119][0]) ? black : white);
}
}
if (TimeControl.clock[white] > 0)
TCflag = true;
fclose (fd);
}
ZeroRPT ();
InitializeStats ();
epsquare = eps;
UpdateDisplay (hWnd, 0, 0, 1, 0);
Sdepth = 0;
hint = 0;
}
void
SaveGame (HWND hWnd, char *fname)
{
FILE *fd;
short sq, i, c, f, t;
char p;
if ((fd = fopen (fname, "w")) != NULL)
{
char *b, *w;
b = w = CP[74];
if (computer == black)
b = CP[141];
if (computer == white)
w = CP[141];
fprintf (fd, CP[37], b, w, Game50,epsquare);
fprintf (fd, CP[42], castld[white] ? CP[214] : CP[215], castld[black] ? CP[214] : CP[215]);
fprintf (fd, CP[111], TCflag, OperatorTime);
fprintf (fd, CP[117],
TimeControl.clock[white], TimeControl.moves[white],
TimeControl.clock[black], TimeControl.moves[black]);
for (i = 7; i > -1; i--)
{
fprintf (fd, "%1d ", i + 1);
for (c = 0; c < 8; c++)
{
sq = i * 8 + c;
switch (color[sq])
{
case black:
p = pxx[board[sq]];
break;
case white:
p = qxx[board[sq]];
break;
default:
p = '.';
}
fprintf (fd, "%c", p);
}
for (f = i * 8; f < i * 8 + 8; f++)
fprintf (fd, " %d", Mvboard[f]);
fprintf (fd, "\n");
}
fprintf (fd, " %s\n", cxx);
fprintf (fd, CP[126]);
for (i = 1; i <= GameCnt; i++)
{
struct GameRec *g = &GameList[i];
f = g->gmove >> 8;
t = (g->gmove & 0xFF);
algbr (f, t, g->flags);
fprintf (fd, "%s %5d %5d %7ld %6ld %5d %#08lx %#08lx %d %c %s\n",
mvstr[0], g->score, g->depth,
g->nodes, g->time, g->flags, g->hashkey, g->hashbd,g->epssq,
pxx[g->piece], ((g->color == 2) ? " " : ColorStr[g->color]));
}
fclose (fd);
/* Game saved */
ShowMessage (hWnd,CP[70]);
}
else
/*ShowMessage ("Could not open file");*/
ShowMessage (hWnd, CP[48]);
}
void
ListGame (void)
{
FILE *fd;
CHAR listfile[128]= "";
short i, f, t;
char fname[256];
if (listfile[0])
strcpy (fname, listfile);
else
{
sprintf (fname, "chess.lst");
}
fd = fopen (fname, "w");
if (!fd)
{
printf ( CP[219], fname);
exit (1);
}
fprintf (fd, CP[161], "65");
fprintf (fd, CP[10]);
fprintf (fd, CP[11]);
for (i = 1; i <= GameCnt; i++)
{
f = GameList[i].gmove >> 8;
t = (GameList[i].gmove & 0xFF);
algbr (f, t, GameList[i].flags);
if(GameList[i].flags & book)
fprintf (fd, "%5s %5d Book%7ld %5d", mvstr[0],
GameList[i].score,
GameList[i].nodes, GameList[i].time);
else
fprintf (fd, "%5s %5d %2d %7ld %5d", mvstr[0],
GameList[i].score, GameList[i].depth,
GameList[i].nodes, GameList[i].time);
if ((i % 2) == 0)
{
fprintf(fd,"\n");
}
}
fprintf (fd, "\n\n");
if (GameList[GameCnt].flags & draw)
{
fprintf (fd, CP[54], DRAW);
}
else if (GameList[GameCnt].score == -9999)
{
fprintf (fd, "%s\n", ColorStr[player ]);
}
else if (GameList[GameCnt].score == 9998)
{
fprintf (fd, "%s\n", ColorStr[player ^ 1]);
}
fclose (fd);
}
void
Undo (HWND hWnd)
/*
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)
(void) castle (GameList[GameCnt].color, f, t, 2);
else
{
/* Check for promotion: */
if ((color[t] == white && row (f) == 6 && row (t) == 7)
|| (color[t] == black && row (f) == 1 && row (t) == 0))
{
int g, from = f;
for (g = GameCnt - 1; g > 0; g--)
if (GameList[g].gmove & 0xFF == from)
from = GameList[g].gmove >> 8;
if ((color[t] == white && row (from) == 1)
|| (color[t] == black && row (from) == 6))
board[t] = pawn;
}
board[f] = board[t];
color[f] = color[t];
board[t] = GameList[GameCnt].piece;
color[t] = GameList[GameCnt].color;
if (color[t] != neutral)
Mvboard[t]--;
Mvboard[f]--;
}
if (TCflag)
++TimeControl.moves[color[f]];
GameCnt--;
computer = otherside[computer];
opponent = otherside[opponent];
flag.mate = false;
Sdepth = 0;
UpdateDisplay (hWnd, 0, 0, 1, 0);
InitializeStats ();
}
void skip ()
{
while (*InPtr != ' ')
InPtr++;
while (*InPtr == ' ')
InPtr++;
}
void skipb ()
{
while (*InPtr == ' ')
InPtr++;
}
int
parser (char *f, int side)
{
int c1, r1, c2, r2;
if (f[4] == 'o')
if (side == black)
return 0x3C3A;
else
return 0x0402;
else if (f[0] == 'o')
if (side == black)
return 0x3C3E;
else
return 0x0406;
else
{
c1 = f[0] - 'a';
r1 = f[1] - '1';
c2 = f[2] - 'a';
r2 = f[3] - '1';
return (locn (r1, c1) << 8) | locn (r2, c2);
}
/*NOTREACHED*/
}