home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume13
/
gnuchess4
/
part06
< prev
next >
Wrap
Internet Message Format
|
1992-08-03
|
56KB
Path: uunet!zephyr.ens.tek.com!master!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v13i094: gnuchess4 - GNU Chess 4.0, Part06/12
Message-ID: <3061@master.CNA.TEK.COM>
Date: 19 Jun 92 15:54:22 GMT
Sender: news@master.CNA.TEK.COM
Lines: 2379
Approved: billr@saab.CNA.TEK.COM
Submitted-by: cracraft@rice-chex.ai.mit.edu (Stuart Cracraft)
Posting-number: Volume 13, Issue 94
Archive-name: gnuchess4/Part06
Supersedes: gnuchess2: Volume 4, Issue 37-40
Environment:
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 6 (of 12)."
# Contents: doc/postprint.1 src/checkbook.c src/dspcom.c
# Wrapped by billr@saab on Fri Jun 19 08:36:01 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'doc/postprint.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'doc/postprint.1'\"
else
echo shar: Extracting \"'doc/postprint.1'\" \(1093 characters\)
sed "s/^X//" >'doc/postprint.1' <<'END_OF_FILE'
X.TH POSTPRINT GNUCHESS
X.SH NAME
Xpostprint
X.SH SYNOPSIS
X.B postprint
Xfilename
X.SH DESCRIPTION
X.I postprint
Xcreates a board by board postscript output file on stdout of the contents of the
X.I gnuchess
Xpersistent hashfile.
XThe hashfile contains information from previous games saved by
X.I gnuchess.
XFor each position it prints the board, the best move for that position
Xand the search depth that generated the move as well as several flags
Xindicating information about the position.
XFlags show whether the score is a true score, or an upper or lower bound on the score
Xand whether or not kingside or queenside castling was legal.
XWhen combined with
X.I ChessFont
Xfile and sent to a postscript printer it will show all boards in the range specified.
XFor each board the move and the current score are also printed.
X.B ChessFont
Xis courtesy of Andy Walker, Maths Dept., Nott'm Univ., UK. (anw@maths.nott.ac.uk)
Xand is copyrighted by him.
X
XTo use:
X
X.B postprint >tmp
X
X.B cat ChessFont tmp | lpr
X
X.SH "FUNCTION LETTERS"
X.TP
X.SH BUGS
X.PP
X.fi
X.SH SEE ALSO
X.nf
Xgnuchess(6)
Xchesstool(6)
Xxboard(6)
X.fi
X
END_OF_FILE
if test 1093 -ne `wc -c <'doc/postprint.1'`; then
echo shar: \"'doc/postprint.1'\" unpacked with wrong size!
fi
# end of 'doc/postprint.1'
fi
if test -f 'src/checkbook.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/checkbook.c'\"
else
echo shar: Extracting \"'src/checkbook.c'\" \(21713 characters\)
sed "s/^X//" >'src/checkbook.c' <<'END_OF_FILE'
X/*
X * checkbook.c - Check a xboard game file or a gnuchess format book for
X * illegal moves. Usage: checkbook [-x] file
X *
X * -x : read xboard game file otherwise read gnuchess book file
X *
X * Limitations: It checks the positions of all pieces of a castling move but
X * does not check that any of the squares crossed is under control of the
X * opponent and does not check that the king or rook have been previously
X * moved. Take it as a TODO.
X *
X * Author M. McGann (mwm@hslrswi.hasler.ascom.ch)
X *
X * Copyright (c) 1992 Free Software Foundation
X *
X * This file is part of GNU CHESS.
X *
X * GNU Chess is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2, or (at your option)
X * any later version.
X *
X * GNU Chess is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with GNU Chess; see the file COPYING. If not, write to
X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X */
X#include <stdio.h>
X#include "gnuchess.h"
X
X#ifdef MSDOS
X#include <stdlib.h>
X#include <string.h>
X#include <time.h>
X#undef RWA_ACC
X#undef WA_ACC
X#define RWA_ACC "rb"
X#define WA_ACC "w+b"
X#else
X#undef RWA_ACC
X#undef WA_ACC
X#define RWA_ACC "r"
X#define WA_ACC "w+"
X#include <sys/param.h>
X#include <sys/types.h>
X#include <sys/times.h>
X#endif /* MSDOS */
XFILE *fd;
X
X#define truescore 0x0001
X#define lowerbound 0x0002
X#define upperbound 0x0004
X#define kingcastle 0x0008
X#define queencastle 0x0010
Xconst short otherside[3] =
X{black, white, neutral};
X
Xstruct GameRec GameList[512];
Xchar mvstr[4][6];
Xlong i, j;
Xshort int ep;
Xint r, c;
Xchar line[128];
Xchar *l;
Xshort int board[64];
Xshort int color[64];
Xshort int GameCnt;
Xint from, to;
Xchar *InPtr;
Xint ckcastld[2];
Xshort int epsquare = -1;
Xint ok;
Xint mvptr = 0;
Xstruct leaf Tree[256];
Xint endflag;
Xint xflag = false;
Xchar mvflag;
Xchar MOVE[256];
X
X/* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
X
Xconst short kingP[3] =
X{4, 60, 0};
Xconst short Stboard[64] =
X{rook, knight, bishop, queen, king, bishop, knight, rook,
X pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X pawn, pawn, pawn, pawn, pawn, pawn, pawn, pawn,
X rook, knight, bishop, queen, king, bishop, knight, rook};
Xconst short Stcolor[64] =
X{white, white, white, white, white, white, white, white,
X white, white, white, white, white, white, white, white,
X neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
X neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
X neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
X neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
X black, black, black, black, black, black, black, black,
X black, black, black, black, black, black, black, black};
Xshort board[64], color[64];
X
X/*
X * nextpos[piece][from-square] , nextdir[piece][from-square] gives vector of
X * positions reachable from from-square in ppos with piece such that the
X * sequence ppos = nextpos[piece][from-square]; pdir =
X * nextdir[piece][from-square]; u = ppos[sq]; do { u = ppos[u]; if(color[u]
X * != neutral) u = pdir[u]; } while (sq != u); will generate the sequence of
X * all squares reachable from sq.
X *
X * If the path is blocked u = pdir[sq] will generate the continuation of the
X * sequence in other directions.
X */
X
Xunsigned char nextpos[8][64][64];
Xunsigned char nextdir[8][64][64];
X
X/*
X * ptype is used to separate white and black pawns, like this; ptyp =
X * ptype[side][piece] piece can be used directly in nextpos/nextdir when
X * generating moves for pieces that are not black pawns.
X */
Xconst short ptype[2][8] =
X{
X no_piece, pawn, knight, bishop, rook, queen, king, no_piece,
X no_piece, bpawn, knight, bishop, rook, queen, king, no_piece};
X
X/* data used to generate nextpos/nextdir */
Xstatic const short direc[8][8] =
X{
X 0, 0, 0, 0, 0, 0, 0, 0,
X 10, 9, 11, 0, 0, 0, 0, 0,
X 8, -8, 12, -12, 19, -19, 21, -21,
X 9, 11, -9, -11, 0, 0, 0, 0,
X 1, 10, -1, -10, 0, 0, 0, 0,
X 1, 10, -1, -10, 9, 11, -9, -11,
X 1, 10, -1, -10, 9, 11, -9, -11,
X -10, -9, -11, 0, 0, 0, 0, 0};
Xstatic const short max_steps[8] =
X{0, 2, 1, 7, 7, 7, 1, 2};
Xstatic const short nunmap[120] =
X{
X -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
X -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
X -1, 0, 1, 2, 3, 4, 5, 6, 7, -1,
X -1, 8, 9, 10, 11, 12, 13, 14, 15, -1,
X -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
X -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
X -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
X -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
X -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
X -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
X -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
X -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
X
Xint InitFlag = false;
X
X
Xvoid
XDISP (void)
X{
X
X short r, c, l;
X
X if (true)
X {
X printf ("\n");
X for (r = 7; r >= 0; r--)
X {
X printf ("%c ", Rxx[r]);
X for (c = 0; c <= 7; c++)
X {
X l = locn (r, c);
X if (color[l] == neutral)
X printf (" -");
X else if (color[l] == white)
X printf (" %c", Qxx[board[l]]);
X else
X printf (" %c", Pxx[board[l]]);
X }
X printf ("\n");
X }
X printf (" a b c d e f g h\n");
X }
X}
X
Xint
Xcastle (short int side, short int kf, short int kt, short int iop)
X
X/* Make or Unmake a castling move. */
X
X{
X register short rf, rt, xside;
X
X xside = otherside[side];
X if (kt > kf)
X {
X rf = kf + 3;
X rt = kt - 1;
X }
X else
X {
X rf = kf - 4;
X rt = kt + 1;
X }
X if (kf != kingP[side] ||
X board[kf] != king ||
X board[rf] != rook ||
X color[kt] != neutral ||
X color[rt] != neutral ||
X color[kt - 1] != neutral)
X return (false);
X else
X return (true);
X}
X
Xvoid
XInitialize_moves (void)
X
X/*
X * This procedure pre-calculates all moves for every piece from every square.
X * This data is stored in nextpos/nextdir and used later in the move
X * generation routines.
X */
X
X{
X short ptyp, po, p0, d, di, s, delta;
X unsigned char *ppos, *pdir;
X short dest[8][8];
X short steps[8];
X short sorted[8];
X
X for (ptyp = 0; ptyp < 8; ptyp++)
X for (po = 0; po < 64; po++)
X for (p0 = 0; p0 < 64; p0++)
X {
X nextpos[ptyp][po][p0] = (unsigned char) po;
X nextdir[ptyp][po][p0] = (unsigned char) po;
X }
X for (ptyp = 1; ptyp < 8; ptyp++)
X for (po = 21; po < 99; po++)
X if (nunmap[po] >= 0)
X {
X ppos = nextpos[ptyp][nunmap[po]];
X pdir = nextdir[ptyp][nunmap[po]];
X /* dest is a function of direction and steps */
X for (d = 0; d < 8; d++)
X {
X dest[d][0] = nunmap[po];
X delta = direc[ptyp][d];
X if (delta != 0)
X {
X p0 = po;
X for (s = 0; s < max_steps[ptyp]; s++)
X {
X p0 = p0 + delta;
X
X /*
X * break if (off
X * board) or (pawns
X * only move two
X * steps from home
X * square)
X */
X if ((nunmap[p0] < 0) || (((ptyp == pawn) || (ptyp == bpawn))
X && ((s > 0) && ((d > 0) || (Stboard[nunmap[po]] != pawn)))))
X break;
X else
X dest[d][s] = nunmap[p0];
X }
X }
X else
X s = 0;
X
X /*
X * sort dest in number of steps order
X * currently no sort is done due to
X * compability with the move
X * generation order in old gnu chess
X */
X steps[d] = s;
X for (di = d; s > 0 && di > 0; di--)
X if (steps[sorted[di - 1]] == 0) /* should be: < s */
X sorted[di] = sorted[di - 1];
X else
X break;
X sorted[di] = d;
X }
X
X /*
X * update nextpos/nextdir, pawns have two
X * threads (capture and no capture)
X */
X p0 = nunmap[po];
X if (ptyp == pawn || ptyp == bpawn)
X {
X for (s = 0; s < steps[0]; s++)
X {
X ppos[p0] = (unsigned char) dest[0][s];
X p0 = dest[0][s];
X }
X p0 = nunmap[po];
X for (d = 1; d < 3; d++)
X {
X pdir[p0] = (unsigned char) dest[d][0];
X p0 = dest[d][0];
X }
X }
X else
X {
X pdir[p0] = (unsigned char) dest[sorted[0]][0];
X for (d = 0; d < 8; d++)
X for (s = 0; s < steps[sorted[d]]; s++)
X {
X ppos[p0] = (unsigned char) dest[sorted[d]][s];
X p0 = dest[sorted[d]][s];
X if (d < 7)
X pdir[p0] = (unsigned char) dest[sorted[d + 1]][0];
X
X /*
X * else is already
X * initialized
X */
X }
X }
X }
X}
X
X#define Link(from,to,flag,s) \
X{\
X node->f = from; node->t = to;\
X node->reply = 0;\
X node->flags = flag;\
X node->score = s;\
X ++node;\
X ++mvptr;\
X }
X
Xinline void
XLinkMove (short int ply,
X short int f,
X short int t,
X short int flag,
X short int xside)
X
X/*
X * Add a move to the tree. Assign a bonus to order the moves as follows: 1.
X * Principle variation 2. Capture of last moved piece 3. Other captures
X * (major pieces first) 4. Killer moves 5.
X */
X
X{
X register short s;
X register unsigned short mv;
X register struct leaf *node;
X
X s = 0;
X node = &Tree[mvptr];
X mv = (f << 8) | t;
X if (row (t) == 0 || row (t) == 7)
X {
X flag |= promote;
X Link (f, t, flag | queen, s - 20000);
X Link (f, t, flag | knight, s - 20000);
X Link (f, t, flag | rook, s - 20000);
X flag |= bishop;
X }
X else if (row (t) == 1 || row (t) == 6)
X {
X flag |= pwnthrt;
X }
X Link (f, t, flag, s - 20000);
X}
X
X
Xvoid
XGenMoves (register short int ply, register short int sq, short int side, short int xside)
X
X/*
X * Generate moves for a piece. The moves are taken from the precalulated
X * array nextpos/nextdir. If the board is free, next move is choosen from
X * nextpos else from nextdir.
X */
X
X{
X register short u, piece;
X register unsigned char *ppos, *pdir;
X
X mvptr = 0;
X piece = board[sq];
X ppos = nextpos[ptype[side][piece]][sq];
X pdir = nextdir[ptype[side][piece]][sq];
X if (piece == pawn)
X {
X u = ppos[sq]; /* follow no captures thread */
X if (color[u] == neutral)
X {
X LinkMove (ply, sq, u, 0, xside);
X u = ppos[u];
X if (color[u] == neutral)
X LinkMove (ply, sq, u, 0, xside);
X }
X u = pdir[sq]; /* follow captures thread */
X if (color[u] == xside)
X LinkMove (ply, sq, u, capture, xside);
X else if (u == epsquare)
X LinkMove (ply, sq, u, capture | epmask, xside);
X u = pdir[u];
X if (color[u] == xside)
X LinkMove (ply, sq, u, capture, xside);
X else if (u == epsquare)
X LinkMove (ply, sq, u, capture | epmask, xside);
X
X }
X else
X {
X u = ppos[sq];
X do
X {
X if (color[u] == neutral)
X {
X LinkMove (ply, sq, u, 0, xside);
X u = ppos[u];
X }
X else
X {
X if (color[u] == xside)
X LinkMove (ply, sq, u, capture, xside);
X u = pdir[u];
X }
X } while (u != sq);
X }
X}
Xvoid
Xskip ()
X{
X while (*InPtr != ' ' && *InPtr != '\n')
X InPtr++;
X while (*InPtr == ' ' && *InPtr != '\n')
X InPtr++;
X}
Xvoid
Xskipb ()
X{
X while (*InPtr == ' ')
X InPtr++;
X}
Xint
Xparser (char *f, int side, short *flags)
X{
X int c1, r1, c2, r2;
X
X *flags = 0;
X
X if (f[4] == 'o')
X if (side == black)
X return 0x3C3A;
X else
X return 0x0402;
X else if (f[0] == 'o')
X if (side == black)
X return 0x3C3E;
X else
X return 0x0406;
X else
X {
X c1 = f[0] - 'a';
X r1 = f[1] - '1';
X c2 = f[2] - 'a';
X r2 = f[3] - '1';
X if ((f[4] != ' ') && (f[4] != '\n') && f[4] != '?')
X {
X /* promotion */
X for (i = 0; i < sizeof (Qxx); i++)
X if (f[4] == Qxx[i])
X {
X *flags = (i | promote);
X break;
X }
X }
X return (locn (r1, c1) << 8) | locn (r2, c2);
X }
X /*NOTREACHED*/
X}
X
Xvoid
Xalgbr (short int f, short int t, short int flag)
X
X
X/*
X * Generate move strings in different formats.
X */
X
X{
X int m3p;
X
X if (f != t)
X {
X /* algebraic notation */
X mvstr[0][0] = Cxx[column (f)];
X mvstr[0][1] = Rxx[row (f)];
X mvstr[0][2] = Cxx[column (t)];
X mvstr[0][3] = Rxx[row (t)];
X mvstr[0][4] = mvstr[3][0] = '\0';
X if (((mvstr[1][0] = Pxx[board[f]]) == 'P') || (flag & promote))
X {
X if (mvstr[0][0] == mvstr[0][2]) /* pawn did not eat */
X {
X mvstr[2][0] = mvstr[1][0] = mvstr[0][2]; /* to column */
X mvstr[2][1] = mvstr[1][1] = mvstr[0][3]; /* to row */
X m3p = 2;
X }
X else
X /* pawn ate */
X {
X mvstr[2][0] = mvstr[1][0] = mvstr[0][0]; /* column */
X mvstr[2][1] = mvstr[1][1] = mvstr[0][2]; /* to column */
X mvstr[2][2] = mvstr[0][3];
X m3p = 3; /* to row */
X }
X if (flag & promote)
X {
X mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = Qxx[flag & pmask];
X mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
X#ifdef CHESSTOOL
X mvstr[3][0] = mvstr[0][0]; /* Allow e7e8 for
X * chesstool */
X mvstr[3][1] = mvstr[0][1];
X mvstr[3][2] = mvstr[0][2];
X mvstr[3][3] = mvstr[0][3];
X mvstr[3][4] = '\0';
X#endif
X }
X mvstr[2][m3p] = mvstr[1][2] = '\0';
X }
X else
X /* not a pawn */
X {
X mvstr[2][0] = mvstr[1][0];
X mvstr[2][1] = mvstr[0][1];
X mvstr[2][2] = mvstr[1][1] = mvstr[0][2]; /* to column */
X mvstr[2][3] = mvstr[1][2] = mvstr[0][3]; /* to row */
X mvstr[2][4] = mvstr[1][3] = '\0';
X strcpy (mvstr[3], mvstr[2]);
X mvstr[3][1] = mvstr[0][0];
X if (flag & cstlmask)
X {
X if (t > f)
X {
X strcpy (mvstr[1], "o-o");
X strcpy (mvstr[2], "O-O");
X }
X else
X {
X strcpy (mvstr[1], "o-o-o");
X strcpy (mvstr[2], "O-O-O");
X }
X }
X }
X }
X else
X mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
X}
Xchar fb[256];
Xint
Xcheckend (char *p)
X{
X int j, l;
X char *q;
X if (xflag)
X {
X if (!strcmp (MOVE, "White"))
X return true;
X if (!strcmp (MOVE, "Black"))
X return true;
X if (!strcmp (MOVE, "draw"))
X return true;
X }
X for (q = MOVE; *p != ' ' && *p != '\t' && *p != '\n'; p++)
X {
X *q++ = *p;
X } *q = '\0';
X l = strlen (MOVE);
X if (l == 2)
X {
X j = MOVE[1] - 'a';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X j = MOVE[2] - '0';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X return false;
X }
X else if (l == 3)
X {
X if (!strcmp (MOVE, "o-o"))
X return false;
X for (j = 0; j < sizeof (Qxx); j++)
X if (MOVE[0] == Qxx[j])
X {
X return false;
X }
X j = MOVE[1] - 'a';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X j = MOVE[2] - '0';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X return false;
X }
X else if (l == 5)
X {
X if (!strcmp (MOVE, "o-o-o"))
X return false;
X }
X else if (l != 4)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X /* check for a legal move */
X j = MOVE[0] - 'a';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X j = MOVE[1] - '0';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X j = MOVE[2] - 'a';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X j = MOVE[3] - '0';
X if (j < 0 || j > 8)
X {
X printf ("illegal move %s\n", fb);
X exit (1);
X }
X if (l == 4)
X return false;
X if (MOVE[4] == '?')
X return false;
X if (MOVE[4] == 'p')
X {
X printf ("illegal promotion??? %s", fb);
X exit (1);
X }
X for (j = 0; j < sizeof (Qxx); j++)
X if (MOVE[4] == Qxx[j])
X {
X return false;
X }
X printf ("illegal promotion??? %s", fb);
X exit (1);
X return true;
X}
X
Xchar title[256];
Xint firsttime = true;
X
XGetGame ()
X{
X struct GameRec *g;
X int side = white;
X
X if (firsttime)
X {
X if (xflag)
X {
X fgets (fb, 256, fd);
X fgets (fb, 256, fd);
X fgets (fb, 256, fd);
X }
X fgets (fb, 256, fd);
X firsttime = false;
X }
X do
X {
X if ((fb[0] == '!') || (fb[0] == '#'))
X {
X if (!GameCnt)
X {
X strcpy (title, fb);
X continue;
X }
X else
X return 0;
X }
X InPtr = fb;
X skipb ();
X if (*InPtr == '\n')
X continue;
X if (isdigit (*InPtr))
X {
X skip ();
X if (*InPtr == '\n')
X continue;
X }
X if (checkend (InPtr))
X {
X if (GameCnt)
X return 0;
X else
X {
X printf ("No moves???\n");
X exit (1);
X }
X }
X ++GameCnt;
X g = &GameList[GameCnt];
X g->gmove = parser (InPtr, side, &(g->flags));
X skip ();
X if (*InPtr == '\n')
X continue;
X if (checkend (InPtr))
X {
X if (GameCnt)
X return 0;
X else
X {
X printf ("No moves???\n");
X exit (1);
X }
X }
X ++GameCnt;
X side = otherside[side];
X g = &GameList[GameCnt];
X g->gmove = parser (InPtr, side, &(g->flags));
X side = otherside[side];
X
X } while (fgets (fb, 256, fd) != NULL);
X return -1;
X}
Xshort int xside, side;
Xint
Xgetboard (int mvno)
X
X{
X register short int f, t;
X short int rf, rt;
X unsigned short mv;
X
X
X /* now update the board and hash values */
X
X /*
X * should really check the moves as we do this, but???
X */
X mv = GameList[mvno].gmove;
X f = mv >> 8 & 0x7F;
X t = mv & 0xFF;
X /* can only capture other side */
X if (board[t] != no_piece)
X {
X if (color[t] != xside)
X {
X algbr (f, t, 0);
X printf ("\nIllegal move - %d %s \n", mvno, mvstr);
X }
X }
X /* there must be a piece to move */
X if (board[f] == no_piece || color[f] != side)
X {
X algbr (f, t, 0);
X printf ("\nIllegal move + %d %s \n", mvno, mvstr);
X }
X /* is it EnPassant */
X
X if (board[f] == pawn && board[t] == no_piece)
X {
X if ((row (f) == 3 &&
X row (t) == 2) || (row (f) == 4 && row (t) == 5))
X {
X if (column (t) != column (f))
X {
X ep = t + ((t > f) ? -8 : 8);
X if (board[ep] == pawn && color[ep] == xside)
X {
X mvflag = 'e';
X board[ep] = no_piece;
X color[ep] = neutral;
X }
X }
X }
X }
X board[t] = board[f];
X color[t] = color[f];
X color[f] = neutral;
X board[f] = no_piece;
X /* castle moves */
X if ((mv == BLACKCASTLE) || (mv == WHITECASTLE) || (mv == LONGBLACKCASTLE) || (mv == LONGWHITECASTLE))
X {
X
X if (t > f)
X {
X rf = f + 3;
X rt = t - 1;
X }
X else
X {
X rf = f - 4;
X rt = t + 1;
X }
X if ((board[t] == king && color[t] == side) && (board[rf] == rook) && (color[rf] == side))
X {
X mvflag = 'c';
X board[rt] = rook;
X color[rt] = side;
X board[rf] = no_piece;
X color[rf] = neutral;
X ckcastld[side] = true;
X }
X }
X else if (GameList[i].flags & promote)
X {
X board[t] = GameList[i].flags & pmask;
X color[t] = side;
X }
X}
X
Xint
Xmain (int argc, char **argv)
X{
X int from, to;
X unsigned short int mv;
X int start, end;
X int ii, kf, jj;
X int filearg = 1;
X
X Initialize_moves ();
X
X if ((argc < 2) || (argc > 3))
X {
X printf ("Usage: checkbook file \n");
X exit (1);
X }
X if (argc == 3)
X {
X if (strcmp (argv[1], "-x"))
X {
X printf ("illegal flag %s\n", argv[1]);
X exit (1);
X }
X xflag = true;
X filearg = 2;
X }
X if ((fd = fopen (argv[filearg], RWA_ACC)) == NULL)
X exit (1);
X endflag = 0;
X while (true)
X {
X if (endflag < 0)
X exit (0);
X start = end = 0;
X ckcastld[0] = ckcastld[1] = false;
X
X side = white;
X xside = black;
X for (i = 0; i < 64; i++)
X {
X board[i] = Stboard[i];
X color[i] = Stcolor[i];
X }
X i = 1;
X GameCnt = 0;
X while (GameCnt == 0)
X {
X if ((endflag = GetGame ()) < 0)
X if (!GameCnt)
X exit (0);
X }
X printf ("-->%s %d\n", title, GameCnt);
X start = 1;
X end = GameCnt + 1;
X side = white;
X xside = black;
X for (i = 1; i < end; i++)
X {
X mvflag = ' ';
X mv = GameList[i].gmove;
X from = mv >> 8 & 0x7F;
X to = mv & 0x7F;
X algbr (from, to, 0);
X
X GenMoves (0, from, side, xside);
X if (!ckcastld[side] && board[from] == king && color[from] == side)
X {
X if (castle (side, from, from + 2, 0))
X {
X LinkMove (0, from, from + 2, cstlmask, xside);
X }
X if (castle (side, from, from - 2, 0))
X {
X LinkMove (0, from, from - 2, cstlmask, xside);
X }
X }
X ok = false;
X for (ii = 0; ii < mvptr; ii++)
X {
X if (from == Tree[ii].f && to == Tree[ii].t)
X {
X ok = true;
X break;
X }
X }
X if (!ok)
X {
X algbr (from, to, 0);
X printf ("\nIllegal move %s\n", mvstr);
X for (ii = 0; ii < mvptr; ii++)
X {
X algbr (Tree[ii].f, Tree[ii].t, 0);
X printf (" %s\n", mvstr);
X }
X DISP ();
X exit (1);
X }
X getboard (i);
X if (side)
X printf ("%s%c\n", mvstr, mvflag);
X else
X {
X printf ("%d. ", 1 + ((i - 1) / 2));
X printf ("%s%c ", mvstr, mvflag);
X }
X if (board[to] == pawn)
X if (to - from == 16)
X epsquare = from + 8;
X else if (from - to == 16)
X epsquare = from - 8;
X else
X epsquare = -1;
X kf = -1;
X for (ii = 0; ii < 64; ii++)
X {
X if ((board[ii] == king) && (color[ii] == side))
X {
X kf = ii;
X break;
X }
X }
X if (kf < 0)
X {
X printf ("Badnews: you have no king\n");
X DISP ();
X exit (1);
X
X }
X for (ii = 0; ii < 64; ii++)
X {
X if (color[ii] == xside)
X {
X mvptr = 0;
X GenMoves (0, ii, xside, side);
X for (jj = 0; jj < mvptr; jj++)
X {
X if (Tree[jj].t == kf)
X {
X
X printf ("Badnews: you are in check\n");
X printf ("king is at %c%c\n", Cxx[column (kf)], Rxx[row (kf)]);
X algbr (Tree[jj].f, Tree[jj].t, 0);
X printf ("move is %s\n", mvstr);
X DISP ();
X exit (1);
X }
X }
X }
X }
X xside = side;
X side = otherside[side];
X }
X printf ("\n\n");
X if (xflag)
X {
X printf ("Final position:\n\n");
X DISP ();
X exit (0);
X }
X }
X /*NOTREACHED*/
X}
END_OF_FILE
if test 21713 -ne `wc -c <'src/checkbook.c'`; then
echo shar: \"'src/checkbook.c'\" unpacked with wrong size!
fi
# end of 'src/checkbook.c'
fi
if test -f 'src/dspcom.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/dspcom.c'\"
else
echo shar: Extracting \"'src/dspcom.c'\" \(28242 characters\)
sed "s/^X//" >'src/dspcom.c' <<'END_OF_FILE'
X/*
X * dspcom.c - C source for GNU CHESS
X *
X * Copyright (c) 1988,1989,1990 John Stanback
X * Copyright (c) 1992 Free Software Foundation
X *
X * This file is part of GNU CHESS.
X *
X * GNU Chess is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2, or (at your option)
X * any later version.
X *
X * GNU Chess is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with GNU Chess; see the file COPYING. If not, write to
X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X */
X#include "gnuchess.h"
X#include "ataks.h"
Xextern char *version, *patchlevel;
Xchar mvstr[4][6];
Xchar *InPtr;
X
X
X#include <ctype.h>
X#include <signal.h>
X#ifdef MSDOS
X#include <dos.h>
X#include <conio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <time.h>
X#else
X#include <sys/param.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/ioctl.h>
X#endif
X
Xvoid
Xalgbr (short int f, short int t, short int flag)
X
X
X/*
X * Generate move strings in different formats.
X */
X
X{
X int m3p;
X
X if (f != t)
X {
X /* algebraic notation */
X mvstr[0][0] = cxx[column (f)];
X mvstr[0][1] = rxx[row (f)];
X mvstr[0][2] = cxx[column (t)];
X mvstr[0][3] = rxx[row (t)];
X mvstr[0][4] = mvstr[3][0] = '\0';
X if (((mvstr[1][0] = pxx[board[f]]) == 'P') || (flag & promote))
X {
X if (mvstr[0][0] == mvstr[0][2]) /* pawn did not eat */
X {
X mvstr[2][0] = mvstr[1][0] = mvstr[0][2]; /* to column */
X mvstr[2][1] = mvstr[1][1] = mvstr[0][3]; /* to row */
X m3p = 2;
X }
X else
X /* pawn ate */
X {
X mvstr[2][0] = mvstr[1][0] = mvstr[0][0]; /* column */
X mvstr[2][1] = mvstr[1][1] = mvstr[0][2]; /* to column */
X mvstr[2][2] = mvstr[0][3];
X m3p = 3; /* to row */
X }
X if (flag & promote)
X {
X mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
X mvstr[0][5] = mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[3][0] = '\0';
X#ifdef CHESSTOOL
X mvstr[3][0] = mvstr[0][0]; /* Allow e7e8 for chesstool */
X mvstr[3][1] = mvstr[0][1];
X mvstr[3][2] = mvstr[0][2];
X mvstr[3][3] = mvstr[0][3];
X mvstr[3][4] = '\0';
X#endif
X }
X mvstr[2][m3p] = mvstr[1][2] = '\0';
X }
X else
X /* not a pawn */
X {
X mvstr[2][0] = mvstr[1][0];
X mvstr[2][1] = mvstr[0][1];
X mvstr[2][2] = mvstr[1][1] = mvstr[0][2]; /* to column */
X mvstr[2][3] = mvstr[1][2] = mvstr[0][3]; /* to row */
X mvstr[2][4] = mvstr[1][3] = '\0';
X strcpy (mvstr[3], mvstr[2]);
X mvstr[3][1] = mvstr[0][0];
X if (flag & cstlmask)
X {
X if (t > f)
X {
X strcpy (mvstr[1], CP[5]);
X strcpy (mvstr[2], CP[7]);
X }
X else
X {
X strcpy (mvstr[1], CP[6]);
X strcpy (mvstr[2], CP[8]);
X }
X }
X }
X }
X else
X mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
X}
X
X
Xint
XVerifyMove (char *s, short int iop, short unsigned int *mv)
X
X/*
X * Compare the string 's' to the list of legal moves available for the
X * opponent. If a match is found, make the move on the board.
X */
X
X{
X static short pnt, tempb, tempc, tempsf, tempst, cnt;
X static struct leaf xnode;
X struct leaf *node;
X
X *mv = 0;
X if (iop == 2)
X {
X UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
X return (false);
X }
X cnt = 0;
X MoveList (opponent, 2);
X pnt = TrPnt[2];
X while (pnt < TrPnt[3])
X {
X node = &Tree[pnt++];
X algbr (node->f, node->t, (short) node->flags);
X if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
X strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
X {
X cnt++;
X xnode = *node;
X }
X }
X if (cnt == 1)
X {
X MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, &INCscore);
X if (SqAtakd (PieceList[opponent][0], computer))
X {
X UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
X#if defined CHESSTOOL
X printz (CP[15]);
X#else
X#ifdef NONDSP
X/* Illegal move in check */
X printz (CP[77]);
X printz ("\n");
X#else
X/* Illegal move in check */
X ShowMessage (CP[77]);
X#endif
X#endif /* CHESSTOOL */
X return (false);
X }
X else
X {
X if (iop == 1)
X return (true);
X UpdateDisplay (xnode.f, xnode.t, 0, (short) xnode.flags);
X if ((board[xnode.t] == pawn)
X || (xnode.flags & capture)
X || (xnode.flags & cstlmask))
X {
X Game50 = GameCnt;
X ZeroRPT ();
X }
X GameList[GameCnt].depth = GameList[GameCnt].score = 0;
X GameList[GameCnt].nodes = 0;
X ElapsedTime (1);
X GameList[GameCnt].time = (short) et;
X if (TCflag)
X {
X TimeControl.clock[opponent] -= et;
X --TimeControl.moves[opponent];
X }
X *mv = (xnode.f << 8) | xnode.t;
X algbr (xnode.f, xnode.t, false);
X return (true);
X }
X }
X#if defined CHESSTOOL
X printz (CP[78]);
X#else
X#ifdef NONDSP
X/* Illegal move */
X printz (CP[75], s);
X#ifdef DEBUG8
X if (1)
X {
X FILE *D;
X int r, c, l;
X extern unsigned short int PrVar[];
X D = fopen ("/tmp/DEBUG", "a+");
X pnt = TrPnt[2];
X fprintf (D, "resp = %d\n", ResponseTime);
X fprintf (D, "iop = %d\n", iop);
X fprintf (D, "matches = %d\n", cnt);
X algbr (hint >> 8, hint & 0xff, (short) 0);
X fprintf (D, "hint %s\n", mvstr[0]);
X fprintf (D, "inout move is %s\n", s);
X for (r = 1; PrVar[r]; r++)
X {
X algbr (PrVar[r] >> 8, PrVar[r] & 0xff, (short) 0);
X fprintf (D, " %s", mvstr[0]);
X }
X fprintf (D, "\n");
X fprintf (D, "legal move are \n");
X while (pnt < TrPnt[3])
X {
X node = &Tree[pnt++];
X algbr (node->f, node->t, (short) node->flags);
X fprintf (D, "%s %s %s %s\n", mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
X }
X fprintf (D, "\n current board is\n");
X for (r = 7; r >= 0; r--)
X {
X for (c = 0; c <= 7; c++)
X {
X l = locn (r, c);
X if (color[l] == neutral)
X fprintf (D, " -");
X else if (color[l] == white)
X fprintf (D, " %c", qxx[board[l]]);
X else
X fprintf (D, " %c", pxx[board[l]]);
X }
X fprintf (D, "\n");
X }
X fprintf (D, "\n");
X fclose (D);
X abort ();
X }
X#endif
X#else
X/* Illegal move */
X ShowMessage (CP[76]);
X#endif
X#endif /* CHESSTOOL */
X#if !defined CHESSTOOL && !defined XBOARD
X if (cnt > 1)
X ShowMessage (CP[32]);
X#endif /* CHESSTOOL */
X return (false);
X}
X
Xint
Xparser (char *f, int side)
X{
X int c1, r1, c2, r2;
X
X if (f[4] == 'o')
X if (side == black)
X return 0x3C3A;
X else
X return 0x0402;
X else if (f[0] == 'o')
X if (side == black)
X return 0x3C3E;
X else
X return 0x0406;
X else
X {
X c1 = f[0] - 'a';
X r1 = f[1] - '1';
X c2 = f[2] - 'a';
X r2 = f[3] - '1';
X return (locn (r1, c1) << 8) | locn (r2, c2);
X }
X /*NOTREACHED*/
X}
X
Xvoid
XGetGame (void)
X{
X FILE *fd;
X char fname[256], *p;
X int c, i, j;
X short sq;
X/* enter file name */
X ShowMessage (CP[63]);
X scanz ("%s", fname);
X/* chess.000 */
X if (fname[0] == '\0')
X strcpy (fname, CP[137]);
X if ((fd = fopen (fname, "r")) != NULL)
X {
X NewGame ();
X fgets (fname, 256, fd);
X computer = opponent = white;
X InPtr = fname;
X skip ();
X if (*InPtr == 'c')
X computer = black;
X else
X opponent = black;
X skip ();
X skip ();
X skip ();
X Game50 = atoi (InPtr);
X fgets (fname, 256, fd);
X InPtr = &fname[14];
X castld[white] = ((*InPtr == CP[214][0]) ? true : false);
X skip ();
X skip ();
X castld[black] = ((*InPtr == CP[214][0]) ? true : false);
X fgets (fname, 256, fd);
X InPtr = &fname[11];
X skipb ();
X TCflag = atoi (InPtr);
X skip ();
X InPtr += 14;
X skipb ();
X OperatorTime = atoi (InPtr);
X fgets (fname, 256, fd);
X InPtr = &fname[11];
X skipb ();
X TimeControl.clock[white] = atoi (InPtr);
X skip ();
X skip ();
X TimeControl.moves[white] = atoi (InPtr);
X fgets (fname, 256, fd);
X InPtr = &fname[11];
X skipb ();
X TimeControl.clock[black] = atoi (InPtr);
X skip ();
X skip ();
X TimeControl.moves[black] = atoi (InPtr);
X fgets (fname, 256, fd);
X for (i = 7; i > -1; i--)
X {
X fgets (fname, 256, fd);
X p = &fname[2];
X InPtr = &fname[11];
X skipb ();
X for (j = 0; j < 8; j++)
X {
X sq = i * 8 + j;
X if (*p == '.')
X {
X board[sq] = no_piece;
X color[sq] = neutral;
X }
X else
X {
X for (c = 0; c < 8; c++)
X {
X if (*p == pxx[c])
X {
X board[sq] = c;
X color[sq] = black;
X }
X }
X for (c = 0; c < 8; c++)
X {
X if (*p == qxx[c])
X {
X board[sq] = c;
X color[sq] = white;
X }
X }
X }
X p++;
X Mvboard[sq] = atoi (InPtr);
X skip ();
X }
X }
X GameCnt = 0;
X flag.regularstart = true;
X Book = BOOKFAIL;
X fgets (fname, 256, fd);
X fgets (fname, 256, fd);
X fgets (fname, 256, fd);
X while (fgets (fname, 256, fd))
X {
X struct GameRec *g;
X int side = computer;
X
X side = side ^ 1;
X ++GameCnt;
X InPtr = fname;
X skipb ();
X g = &GameList[GameCnt];
X g->gmove = parser (InPtr, side);
X skip ();
X g->score = atoi (InPtr);
X skip ();
X g->depth = atoi (InPtr);
X skip ();
X g->nodes = atoi (InPtr);
X skip ();
X g->time = atoi (InPtr);
X skip ();
X g->flags = c = atoi (InPtr);
X skip ();
X g->hashkey = strtol (InPtr, (char **) NULL, 16);
X skip ();
X g->hashbd = strtol (InPtr, (char **) NULL, 16);
X g->piece = no_piece;
X g->color = neutral;
X if (c & (capture | cstlmask))
X {
X if (c & capture)
X {
X skip ();
X for (c = 0; c < 8; c++)
X if (pxx[c] == *InPtr)
X break;
X g->piece = c;
X }
X skip ();
X g->color = ((*InPtr == CP[119][0]) ? black : white);
X }
X }
X /* GameCnt--; */
X if (TimeControl.clock[white] > 0)
X TCflag = true;
X fclose (fd);
X }
X ZeroRPT ();
X InitializeStats ();
X UpdateDisplay (0, 0, 1, 0);
X Sdepth = 0;
X hint = 0;
X}
X
Xvoid
XGetXGame (void)
X{
X FILE *fd;
X char fname[256], *p;
X int c, i, j;
X short sq;
X/* Enter file name */
X ShowMessage (CP[63]);
X scanz ("%s", fname);
X if (fname[0] == '\0')
X/* xboard.position.read*/
X strcpy (fname, CP[205]);
X if ((fd = fopen (fname, "r")) != NULL)
X {
X NewGame ();
X flag.regularstart = false;
X Book = false;
X fgets (fname, 256, fd);
X fname[6] = '\0';
X if (strcmp (fname, CP[206]))
X return;
X fgets (fname, 256, fd);
X fgets (fname, 256, fd);
X for (i = 7; i > -1; i--)
X {
X fgets (fname, 256, fd);
X p = fname;
X for (j = 0; j < 8; j++)
X {
X sq = i * 8 + j;
X if (*p == '.')
X {
X board[sq] = no_piece;
X color[sq] = neutral;
X }
X else
X {
X for (c = 0; c < 8; c++)
X {
X if (*p == qxx[c])
X {
X board[sq] = c;
X color[sq] = black;
X }
X }
X for (c = 0; c < 8; c++)
X {
X if (*p == pxx[c])
X {
X board[sq] = c;
X color[sq] = white;
X }
X }
X }
X p += 2;
X }
X }
X fclose (fd);
X }
X ZeroRPT ();
X InitializeStats ();
X UpdateDisplay (0, 0, 1, 0);
X Sdepth = 0;
X hint = 0;
X}
X
Xvoid
XSaveGame (void)
X{
X FILE *fd;
X char fname[256];
X short sq, i, c, f, t;
X char p;
X
X if (savefile[0])
X strcpy (fname, savefile);
X else
X {
X/* Enter file name*/
X ShowMessage (CP[63]);
X scanz ("%s", fname);
X }
X
X if (fname[0] == '\0')
X/* chess.000 */
X strcpy (fname, CP[137]);
X if ((fd = fopen (fname, "w")) != NULL)
X {
X char *b, *w;
X
X b = w = CP[74];
X if (computer == black)
X b = CP[141];
X if (computer == white)
X w = CP[141];
X fprintf (fd, CP[37], b, w, Game50);
X fprintf (fd, CP[42], castld[white] ? CP[214] : CP[215], castld[black] ? CP[214] : CP[215]);
X fprintf (fd, CP[111], TCflag, OperatorTime);
X fprintf (fd, CP[117],
X TimeControl.clock[white], TimeControl.moves[white],
X TimeControl.clock[black], TimeControl.moves[black]);
X for (i = 7; i > -1; i--)
X {
X fprintf (fd, "%1d ", i + 1);
X for (c = 0; c < 8; c++)
X {
X sq = i * 8 + c;
X switch (color[sq])
X {
X case black:
X p = pxx[board[sq]];
X break;
X case white:
X p = qxx[board[sq]];
X break;
X default:
X p = '.';
X }
X fprintf (fd, "%c", p);
X }
X for (f = i * 8; f < i * 8 + 8; f++)
X fprintf (fd, " %d", Mvboard[f]);
X fprintf (fd, "\n");
X }
X fprintf (fd, " %s\n", cxx);
X fprintf (fd, CP[126]);
X for (i = 1; i <= GameCnt; i++)
X {
X struct GameRec *g = &GameList[i];
X
X f = g->gmove >> 8;
X t = (g->gmove & 0xFF);
X algbr (f, t, g->flags);
X fprintf (fd, "%s %5d %5d %7ld %5d %5d %#08lx %#08lx %c %s\n",
X mvstr[0], g->score, g->depth,
X g->nodes, g->time, g->flags, g->hashkey, g->hashbd,
X pxx[g->piece], ((g->color == 2) ? " " : ColorStr[g->color]));
X }
X fclose (fd);
X/* Game saved */
X ShowMessage (CP[70]);
X }
X else
X /*ShowMessage ("Could not open file");*/
X ShowMessage (CP[48]);
X}
X
Xvoid
XListGame (void)
X{
X FILE *fd;
X short i, f, t;
X long when;
X char fname[256], dbuf[256];
X
X if (listfile[0])
X strcpy (fname, listfile);
X else
X {
X#ifdef MSDOS
X sprintf (fname, "chess.lst");
X#else
X time (&when);
X strncpy (dbuf, ctime (&when), 20);
X dbuf[7] = '\0';
X dbuf[10] = '\0';
X dbuf[13] = '\0';
X dbuf[16] = '\0';
X dbuf[19] = '\0';
X/* use format "CLp16.Jan01-020304B" when patchlevel is 16,
X date is Jan 1
X time is 02:03:04
X program played black */
X sprintf (fname, "CLp%s.%s%s-%s%s%s%c", patchlevel, dbuf + 4, dbuf + 8, dbuf + 11, dbuf + 14, dbuf + 17, ColorStr[computer][0]);
X /* replace space padding with 0 */
X for (i = 0; fname[i] != '\0'; i++)
X if (fname[i] == ' ')
X fname[i] = '0';
X#endif /* MSDOS */
X }
X fd = fopen (fname, "w");
X if (!fd)
X {
X printf (CP[219], fname);
X exit (1);
X }
X /*fprintf (fd, "gnuchess game %d\n", u);*/
X fprintf (fd, CP[161], patchlevel);
X fprintf (fd, CP[10]);
X fprintf (fd, CP[11]);
X for (i = 1; i <= GameCnt; i++)
X {
X f = GameList[i].gmove >> 8;
X t = (GameList[i].gmove & 0xFF);
X algbr (f, t, GameList[i].flags);
X fprintf (fd, "%5s %5d %2d %7ld %5d", mvstr[0],
X GameList[i].score, GameList[i].depth,
X GameList[i].nodes, GameList[i].time);
X if ((i % 2) == 0)
X {
X fprintf (fd, "\n");
X#ifdef DEBUG40
X if (computer == black)
X fprintf (fd, " %d %d %d %ld %d %d\n",
X GameList[i].d1,
X GameList[i].d2,
X GameList[i].d3,
X GameList[i].d4,
X GameList[i].d5,
X GameList[i].d6);
X else
X fprintf (fd, " %d %d %d %ld %d %d\n",
X GameList[i - 1].d1,
X GameList[i - 1].d2,
X GameList[i - 1].d3,
X GameList[i - 1].d4,
X GameList[i - 1].d5,
X GameList[i - 1].d6);
X#endif
X }
X else
X fprintf (fd, " ");
X }
X fprintf (fd, "\n\n");
X if (GameList[GameCnt].flags & draw)
X {
X fprintf (fd, CP[54], DRAW);
X }
X else if (GameList[GameCnt].score == -9999)
X {
X fprintf (fd, "%s\n", ColorStr[player ^ 1]);
X }
X else if (GameList[GameCnt].score == 9998)
X {
X fprintf (fd, "%s\n", ColorStr[player]);
X }
X fclose (fd);
X}
X
Xvoid
XUndo (void)
X
X/*
X * Undo the most recent half-move.
X */
X
X{
X short f, t;
X f = GameList[GameCnt].gmove >> 8;
X t = GameList[GameCnt].gmove & 0xFF;
X if (board[t] == king && distance (t, f) > 1)
X (void) castle (GameList[GameCnt].color, f, t, 2);
X else
X {
X /* Check for promotion: */
X if (GameList[GameCnt].flags & promote)
X {
X board[t] = pawn;
X }
X board[f] = board[t];
X color[f] = color[t];
X board[t] = GameList[GameCnt].piece;
X color[t] = GameList[GameCnt].color;
X if (color[t] != neutral)
X Mvboard[t]--;
X Mvboard[f]--;
X }
X if (GameList[GameCnt].flags & epmask)
X EnPassant (otherside[color[f]], f, t, 2);
X else
X InitializeStats ();
X if (TCflag)
X ++TimeControl.moves[color[f]];
X hashkey = GameList[GameCnt].hashkey;
X hashbd = GameList[GameCnt].hashbd;
X GameCnt--;
X computer = computer ^ 1;
X opponent = opponent ^ 1;
X flag.mate = false;
X Sdepth = 0;
X player = player ^ 1;
X ShowSidetoMove ();
X UpdateDisplay (0, 0, 1, 0);
X if (flag.regularstart)
X Book = BOOKFAIL;
X}
X
Xvoid
X TestSpeed (void (*f) (short int side, short int ply), unsigned j)
X{
X short i;
X long cnt, rate, t1, t2;
X
X t1 = time (0);
X for (i = 0; i < j; i++)
X {
X f (opponent, 2);
X }
X t2 = time (0);
X cnt = j * (TrPnt[3] - TrPnt[2]);
X if (t2 - t1)
X et = (t2 - t1) * 100;
X else
X et = 1;
X rate = (et) ? (cnt / et) : 0;
X /*printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);*/
X#ifdef NONDSP
X printz (CP[91], cnt, rate);
X#ifdef DEBUG9
X for (j = TrPnt[2]; j < TrPnt[3]; j++)
X {
X struct leaf *node = &Tree[j];
X algbr (node->f, node->t, node->flags);
X printf ("%s %s %s %s\n", mvstr[0], mvstr[1], mvstr[2], mvstr[3]);
X }
X#endif
X#else
X ShowNodeCnt (cnt);
X#endif
X}
X
Xvoid
X TestPSpeed (void (*f) (short int side), unsigned j)
X{
X short i;
X long cnt, rate, t1, t2;
X short int t;
X
X t1 = time (0);
X for (i = 0; i < j; i++)
X {
X f (opponent);
X }
X t2 = time (0);
X cnt = j;
X if (t2 - t1)
X et = (t2 - t1) * 100;
X else
X et = 1;
X rate = (et) ? (cnt / et) : 0;
X /*printz ("Nodes= %ld Nodes/sec= %ld\n", cnt, rate);*/
X#ifdef NONDSP
X printz (CP[91], cnt, rate);
X#else
X ShowNodeCnt (cnt);
X#endif
X}
X
X
Xvoid
XSetMachineTime (char *s)
X{
X char *time;
X int m, t;
X time = &s[strlen (CP[197])];
X t = strtol (time, &time, 10);
X m = strtol (time, &time, 10);
X if (t)
X TimeControl.clock[computer] = t;
X if (m)
X TimeControl.moves[computer] = m;
X#ifdef XBOARD
X printz (CP[222], m, t);
X#endif
X}
X
X
Xvoid
XInputCommand (void)
X
X/*
X * Process the users command. If easy mode is OFF (the computer is thinking
X * on opponents time) and the program is out of book, then make the 'hint'
X * move on the board and call SelectMove() to find a response. The user
X * terminates the search by entering ^C (quit siqnal) before entering a
X * command. If the opponent does not make the hint move, then set Sdepth to
X * zero.
X */
X
X{
X int i = 0;
X short have_shown_prompt = false;
X short ok, tmp;
X unsigned short mv;
X char s[80], sx[80];
X
X#if defined CHESSTOOL
X short normal = false;
X
X#endif
X
X ok = flag.quit = false;
X player = opponent;
X ft = 0;
X if (hint > 0 && !flag.easy && !flag.force)
X if ((board[hint >> 8] != pawn) || ((row (hint & 0xFF) != 0) && (row (hint & 0xFF) != 7)))
X {
X fflush (stdout);
X time0 = time ((long *) 0);
X algbr ((short) hint >> 8, (short) hint & 0xFF, false);
X strcpy (s, mvstr[0]);
X tmp = epsquare;
X#ifdef DEBUG12
X if (1)
X {
X FILE *D;
X int r, c, l;
X extern unsigned short int PrVar[];
X extern struct leaf rootnode;
X D = fopen ("/tmp/DEBUGA", "a+");
X fprintf (D, "score = %d\n", rootnode.score);
X fprintf (D, "inout move is %s\n", s);
X for (r = 1; PrVar[r]; r++)
X {
X algbr (PrVar[r] >> 8, PrVar[r] & 0xff, (short) 0);
X fprintf (D, " %s", mvstr[0]);
X }
X fprintf (D, "\n current board is\n");
X for (r = 7; r >= 0; r--)
X {
X for (c = 0; c <= 7; c++)
X {
X l = locn (r, c);
X if (color[l] == neutral)
X fprintf (D, " -");
X else if (color[l] == white)
X fprintf (D, " %c", qxx[board[l]]);
X else
X fprintf (D, " %c", pxx[board[l]]);
X }
X fprintf (D, "\n");
X }
X fprintf (D, "\n");
X fclose (D);
X }
X#endif
X#if !defined XBOARD && !defined CHESSTOOL
X if (flag.post)
X GiveHint ();
X#endif
X if (VerifyMove (s, 1, &mv))
X {
X Sdepth = 0;
X#ifdef QUIETBACKGROUND
X#ifdef NONDSP
X PromptForMove ();
X#else
X ShowSidetoMove ();
X ShowPrompt ();
X#endif
X have_shown_prompt = true;
X#endif /* QUIETBACKGROUND */
X SelectMove (computer, 2);
X VerifyMove (s, 2, &mv);
X Sdepth = 0;
X }
X ft = (time ((long *) 0) - time0) * 100;
X epsquare = tmp;
X }
X while (!(ok || flag.quit))
X {
X#if defined CHESSTOOL
X normal = false;
X#endif
X player = opponent;
X#ifdef QUIETBACKGROUND
X if (!have_shown_prompt)
X {
X#endif /* QUIETBACKGROUND */
X#ifdef NONDSP
X PromptForMove ();
X#else
X ShowSidetoMove ();
X ShowPrompt ();
X#endif
X#ifdef QUIETBACKGROUND
X }
X have_shown_prompt = false;
X#endif /* QUIETBACKGROUND */
X#ifdef NONDSP
X s[0] = sx[0] = '\0';
X while (!sx[0])
X i = (int) gets (sx);
X#else
X fflush (stdout);
X i = (int) getstr (sx);
X#endif
X sscanf (sx, "%s", s);
X if (i == EOF)
X ExitChess ();
X if (s[0] == '\0')
X continue;
X if (strcmp (s, CP[131]) == 0) /*bd*/
X {
X#if defined CHESSTOOL || defined XBOARD
X chesstool = 0;
X#endif /* CHESSTOOL */
X ClrScreen ();
X UpdateDisplay (0, 0, 1, 0);
X#if defined CHESSTOOL || defined XBOARD
X chesstool = 1;
X#endif /* CHESSTOOL */
X }
X else if (strcmp (s, CP[129]) == 0) /* noop */ ; /*alg*/
X else if ((strcmp (s, CP[180]) == 0) || (strcmp (s, CP[216]) == 0)) /* quit exit*/
X flag.quit = true;
X else if (strcmp (s, CP[178]) == 0) /*post*/
X {
X flag.post = !flag.post;
X }
X else if ((strcmp (s, CP[191]) == 0) || (strcmp (s, CP[154]) == 0)) /*set edit*/
X EditBoard ();
X#ifdef NONDSP
X else if (strcmp (s, CP[190]) == 0) /*setup*/
X SetupBoard ();
X#endif
X else if (strcmp (s, CP[156]) == 0) /*first*/
X {
X#if defined CHESSTOOL
X computer = white;
X opponent = black;
X flag.force = false;
X Sdepth = 0;
X#endif /* CHESSTOOL */
X ok = true;
X }
X else if (strcmp (s, CP[162]) == 0) /*go*/
X {
X ok = true;
X flag.force = false;
X if (computer == white)
X {
X computer = black;
X opponent = white;
X }
X else
X {
X computer = white;
X opponent = black;
X }
X }
X else if (strcmp (s, CP[166]) == 0) /*help*/
X help ();
X else if (strcmp (s, CP[221]) == 0) /*material*/
X flag.material = !flag.material;
X else if (strcmp (s, CP[157]) == 0) /*force*/
X flag.force = !flag.force;
X else if (strcmp (s, CP[134]) == 0) /*book*/
X Book = Book ? 0 : BOOKFAIL;
X else if (strcmp (s, CP[172]) == 0) /*new*/
X {
X NewGame ();
X UpdateDisplay (0, 0, 1, 0);
X }
X else if (strcmp (s, CP[171]) == 0) /*list*/
X ListGame ();
X else if (strcmp (s, CP[169]) == 0 || strcmp (s, CP[217]) == 0) /*level clock*/
X SelectLevel ();
X else if (strcmp (s, CP[165]) == 0) /*hash*/
X flag.hash = !flag.hash;
X else if (strcmp (s, CP[132]) == 0) /*beep*/
X flag.beep = !flag.beep;
X else if (strcmp (s, CP[197]) == 0) /*time*/
X {
X SetMachineTime (sx);
X }
X else if (strcmp (s, CP[33]) == 0) /*Awindow*/
X ChangeAlphaWindow ();
X else if (strcmp (s, CP[39]) == 0) /*Bwindow*/
X ChangeBetaWindow ();
X else if (strcmp (s, CP[183]) == 0) /*rcptr*/
X flag.rcptr = !flag.rcptr;
X else if (strcmp (s, CP[168]) == 0) /*hint*/
X GiveHint ();
X else if (strcmp (s, CP[135]) == 0) /*both*/
X {
X flag.bothsides = !flag.bothsides;
X Sdepth = 0;
X ElapsedTime (1);
X SelectMove (opponent, 1);
X ok = true;
X }
X else if (strcmp (s, CP[185]) == 0) /*reverse*/
X {
X flag.reverse = !flag.reverse;
X ClrScreen ();
X UpdateDisplay (0, 0, 1, 0);
X }
X else if (strcmp (s, CP[195]) == 0) /*switch*/
X {
X computer = computer ^ 1;
X opponent = opponent ^ 1;
X xwndw = (computer == white) ? WXWNDW : BXWNDW;
X flag.force = false;
X Sdepth = 0;
X ok = true;
X }
X else if (strcmp (s, CP[203]) == 0) /*white*/
X {
X computer = black;
X opponent = white;
X xwndw = WXWNDW;
X flag.force = false;
X Sdepth = 0;
X
X /*
X * ok = true; don't automatically start with white command
X */
X }
X else if (strcmp (s, CP[133]) == 0) /*black*/
X {
X computer = white;
X opponent = black;
X xwndw = BXWNDW;
X flag.force = false;
X Sdepth = 0;
X
X /*
X * ok = true; don't automatically start with black command
X */
X }
X else if (strcmp (s, CP[201]) == 0 && GameCnt > 0) /*undo*/
X {
X Undo ();
X }
X else if (strcmp (s, CP[184]) == 0 && GameCnt > 1) /*remove*/
X {
X Undo ();
X Undo ();
X }
X else if (strcmp (s, CP[160]) == 0) /*get*/
X GetGame ();
X else if (strcmp (s, CP[207]) == 0) /*xget*/
X GetXGame ();
X else if (strcmp (s, CP[189]) == 0) /*save*/
X SaveGame ();
X else if (strcmp (s, CP[151]) == 0) /*depth*/
X ChangeSearchDepth ();
X#ifdef DEBUG
X else if (strcmp (s, CP[147]) == 0) /*debuglevel*/
X ChangeDbLev ();
X#endif /* DEBUG */
X else if (strcmp (s, CP[164]) == 0) /*hashdepth*/
X ChangeHashDepth ();
X else if (strcmp (s, CP[182]) == 0) /*random*/
X dither = DITHER;
X else if (strcmp (s, CP[152]) == 0) /*easy*/
X flag.easy = !flag.easy;
X else if (strcmp (s, CP[143]) == 0) /*contempt*/
X SetContempt ();
X else if (strcmp (s, CP[209]) == 0) /*xwndw*/
X ChangeXwindow ();
X else if (strcmp (s, CP[186]) == 0) /*rv*/
X {
X flag.rv = !flag.rv;
X UpdateDisplay (0, 0, 1, 0);
X }
X else if (strcmp (s, CP[145]) == 0) /*coords*/
X {
X flag.coords = !flag.coords;
X UpdateDisplay (0, 0, 1, 0);
X }
X else if (strcmp (s, CP[193]) == 0) /*stras*/
X {
X flag.stars = !flag.stars;
X UpdateDisplay (0, 0, 1, 0);
X }
X else if (strcmp (s, CP[196]) == 0) /*test*/
X {
X ShowMessage (CP[108]);/*test movelist*/
X TestSpeed (MoveList, 20000);
X ShowMessage (CP[107]);/*test capturelist*/
X TestSpeed (CaptureList, 30000);
X ShowMessage (CP[107]);/*test capturelist*/
X TestPSpeed ((void *) ScorePosition, 15000);
X }
X else
X#if !defined NONDSP
X if (strcmp (s, CP[179]) == 0) /*p*/
X ShowPostnValues ();
X else if (strcmp (s, CP[148]) == 0) /*debug*/
X DoDebug ();
X else
X#endif
X {
X#if defined CHESSTOOL
X normal = (ok = VerifyMove (s, 0, &mv));
X#else
X ok = VerifyMove (s, 0, &mv);
X#endif
X if ((ok && mv != hint))
X {
X Sdepth = 0;
X ft = 0;
X }
X else
X Sdepth = 0;
X }
X }
X
X ElapsedTime (1);
X if (flag.force)
X {
X computer = opponent;
X opponent = computer ^ 1;
X }
X#if defined CHESSTOOL || defined XBOARD
X#if defined CHESSTOOL
X if (normal)
X if (computer == white)
X printz ("%d. %s", ++mycnt2, s);
X else
X printz ("%d. ... %s", ++mycnt2, s);
X#else
X printz ("%d. %s\n", ++mycnt2, s);
X#endif
X#ifdef notdef
X if (flag.post)
X {
X register int i;
X
X printz (" %6d ", MSCORE);
X for (i = 1; MV[i] > 0; i++)
X {
X algbr ((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
X printz ("%5s ", mvstr[0]);
X }
X }
X printz ("\n");
X#endif
X#endif /* CHESSTOOL */
X signal (SIGINT, TerminateSearch);
X#ifndef MSDOS
X signal (SIGQUIT, TerminateSearch);
X#endif /* MSDOS */
X}
X
Xvoid
XElapsedTime (short int iop)
X
X
X/*
X * Determine the time that has passed since the search was started. If the
X * elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout
X * to true which will terminate the search. iop = 0 calculate et bump ETnodes
X * iop = 1 calculate et set timeout if time exceeded, calculate et
X */
X
X{
X#ifndef MSDOS
X long nchar;
X extern int errno;
X int i;
X#ifdef FIONREAD
X if (i = ioctl ((int) 0, FIONREAD, &nchar))
X {
X printf ("ioctl failure is this gcc 2.00? See README %d %d\n", i, errno);
X perror ("FIONREAD");
X exit ();
X }
X
X if (nchar)
X {
X if (!flag.timeout)
X flag.musttimeout = true;
X flag.bothsides = false;
X }
X#endif /*FIONREAD*/
X#else
X if (kbhit ())
X {
X if (!flag.timeout)
X flag.musttimeout = true;
X flag.bothsides = false;
X }
X#endif /* MSDOS */
X et = (time ((long *) 0) - time0) * 100;
X ETnodes = NodeCnt + ZNODES;
X if (et < 0)
X et = 0;
X if (iop == 1)
X {
X if (et > ResponseTime + ExtraTime && Sdepth > MINDEPTH)
X flag.timeout = true;
X ETnodes = NodeCnt + ZNODES;
X time0 = time ((long *) 0);
X }
X#if !defined NONDSP
X#ifdef QUIETBACKGROUND
X if (!background)
X#endif /* QUIETBACKGROUND */
X UpdateClocks ();
X#endif
X}
X
Xvoid
XSetTimeControl (void)
X{
X if (TCflag)
X {
X TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
X TimeControl.clock[white] = TimeControl.clock[black] = 6000L * TCminutes + TCseconds * 100;
X }
X else
X {
X TimeControl.moves[white] = TimeControl.moves[black] = 0;
X TimeControl.clock[white] = TimeControl.clock[black] = 0;
X Level = TCminutes;
X }
X et = 0;
X ElapsedTime (1);
X}
END_OF_FILE
if test 28242 -ne `wc -c <'src/dspcom.c'`; then
echo shar: \"'src/dspcom.c'\" unpacked with wrong size!
fi
# end of 'src/dspcom.c'
fi
echo shar: End of archive 6 \(of 12\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 12 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
echo Building book file.
cat misc/book.xaa misc/book.xab > misc/gnuchess.nunn.book
rm misc/book.xaa misc/book.xab
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0