/*
 * gnuchess.h - Header file for GNU CHESS
 *
 * Copyright (c) 1988,1989,1990 John Stanback
 * Copyright (c) 1992 Free Software Foundation
 *
 * This file is part of GNU CHESS.
 *
 * GNU Chess is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * GNU Chess is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Chess; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#if !defined(__STDC__) || !defined(MSDOS)
#define const
#endif

#ifndef __GNUC__
#define inline
#endif

#include <stdio.h>

#define SEEK_SET 0
#define SEEK_END 2
#ifdef DEBUG
void
ShowDBLine (char *, short int, short int,
	    short int, short int, short int,
	    short unsigned int *);
     extern FILE *debugfd;
     extern short int debuglevel;

#endif /* DEBUG */

#include <ctype.h>

#ifdef MSDOS
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define RWA_ACC "r+b"
#define WA_ACC "w+b"
#else
#define RWA_ACC "r+"
#define WA_ACC "w+"
#ifndef AMIGA
#include <sys/param.h>
#endif
#include <sys/types.h>
#ifndef AMIGA
#include <sys/times.h>
#endif
#endif /* MSDOS */
#ifdef NONDSP
#define printz printf
#define scanz scanf
#else
#ifdef AMIGA
#include "amiga/amiterm.h"
#define scanz ami_scanw
extern char *libdir;
#else
#include <curses.h>
#define scanz fflush(stdout), scanw
#endif
#define printz printw
#endif

#ifndef AMIGA
#if defined(__STDC__) || defined(MSDOS)
/* <stdio.h> */
     extern int fclose (FILE *);
#ifndef __ultrix /* work around bug in c89 compiler --t.mann */
     extern int fscanf (FILE *, const char *, ...);
     extern int fprintf (FILE *, const char *, ...);
#endif /*__ultrix*/
     extern int fflush (FILE *);

/* <stdlib.h> */
     extern int abs (int);
     extern int atoi (const char *);

/* <time.h> */
     extern long int time (long int *);

/* <string.h> */
     extern void *memset (void *, int, size_t);
#endif
#endif /* AMIGA */

/* Piece values */
#define valueP 100
#define valueN 350
#define valueB 355
#define valueR 550
#define valueQ 1100
#define valueK 1200
/* masks into upper 8 bits of ataks array */
#define ctlP 0x4000
#define ctlN 0x2800
#define ctlB 0x1800
#define ctlR 0x0400
#define ctlQ 0x0200
#define ctlK 0x0100
#define ctlBQ 0x1200
#define ctlBN 0x0800
#define ctlRQ 0x0600
#define ctlNN 0x2000
/* attack functions */
#define Patak(c, u) (atak[c][u] > ctlP)
#define Anyatak(c, u) (atak[c][u] > 0)
/* distance function */
#define taxicab(a,b) taxidata[a][b]
/* hashtable flags */
#define truescore 0x0001
#define lowerbound 0x0002
#define upperbound 0x0004
#define kingcastle 0x0008
#define queencastle 0x0010
/* king positions */
#define wking PieceList[white][0]
#define bking PieceList[black][0]
#define EnemyKing PieceList[c2][0]
/* constants */
/* castle moves */
#define BLACKCASTLE	0x3C3E
#define WHITECASTLE	0x0406
#define LONGBLACKCASTLE	0x3C3A
#define LONGWHITECASTLE	0x0402
/* truth values */
#define false 0
#define true 1
/* colors */
#define white 0
#define black 1
#define neutral 2
/* piece code defines */
#define no_piece 0
#define pawn 1
#define knight 2
#define bishop 3
#define rook 4
#define queen 5
#define king 6
#define bpawn 7
/* node flags */
#define pmask 0x0007
#define promote 0x0008
#define cstlmask 0x0010
#define epmask 0x0020
#define exact 0x0040
#define pwnthrt 0x0080
#define check 0x0100
#define capture 0x0200
#define draw 0x0400
/* move symbols */
#define pxx (CP[2])
#define qxx (CP[1])
#define rxx (CP[4])
#define cxx (CP[3])
/* for everything that can't use the above */
#define Qxx " pnbrqk"
#define Pxx " PNBRQK"
#define Cxx "abcdefgh"
#define Rxx "12345678"
/***************************************************************************/
/***************** Table limits ********************************************/
/*
 * ttblsz must be a power of 2. Setting ttblsz 0 removes the transposition
 * tables.
 */
#if defined(MSDOS) || defined(AMIGA)
#define vttblsz 0 /*(1 << 11)*/
#else
#define vttblsz (1 << 17)
#define huge
#endif /* MSODS */

#define ttblsz vttblsz
#define TREE 1500		/* max number of tree entries */
#define MAXDEPTH 35		/* max depth a search can be carried */
#define MINDEPTH 3		/* min search depth =1 (no hint), >1 hint */
#define MAXMOVES 400		/* max number of half moves in a game */
#ifdef AMIGA
#define BOOKSIZE 10000		/* Number of unique position/move combinations allowed */
#else
#define BOOKSIZE 30000		/* Number of unique position/move combinations allowed */
#endif
#define CPSIZE 226		/* size of lang file max */
/***************** tuning paramaters **********************************************/
#define CHKDEPTH 1		/* always look forward CHKDEPTH half-moves if in check */
#define DEPTHBEYOND 11		/* Max to go beyond Sdepth */
#define HASHDEPTH 4		/* depth above which to use HashFile */
#define HASHMOVELIMIT 40	/* Use HashFile only for this many moves */
#define PTVALUE 2000	        /* material value below which pawn threats at 5 & 3 are used */
#define ZDEPTH 3		/* depth beyond which to check ZDELTA for extra time */
#define ZDELTA 10		/* score delta per ply to cause extra time to be given */
#define ZNODES 1000		/* check the time every ZNODES positions */
#define MAXTCCOUNT 4		/* max number of time clicks per search */
#define MINSEARCHPCT 10		/* must have looked at MINSEARCHPCT moves on a ply on a timeout */
#define SCORETIME -50		/* score below which to add search time */
#define SCORESPLIM 8		/* Score space doesn't apply after this stage */
#define HISTORYLIM 155		/* Max value of history killer */
#define EWNDW 10		/* Eval window to force position scoring at depth greater than Sdepth + 2 */
#define WAWNDW 90		/* alpha window when computer white*/
#define WBWNDW 90		/* beta window when computer white*/
#define BAWNDW 90		/* alpha window when computer black*/
#define BBWNDW 90		/* beta window when computer black*/
#define BXWNDW 90		/* window to force position scoring at lower */
#define WXWNDW 90		/* window to force position scoring at lower */
#define DITHER 2		/* 1+max amount random can alter a pos value */
#define BBONUS 2		/* points per stage value of B increases */
#define RBONUS 6		/* points per stage value of R increases */
#define KINGPOSLIMIT ( -1)	/* King positional scoring limit */
#define KINGSAFETY  16
#define MAXrehash (6)

#if defined AG0
#define WHITEAG0
#define BLACKAG0

#elif defined AG1
#define WHITEAG1
#define BLACKAG1

#elif defined AG2
#define WHITEAG2
#define BLACKAG2

#elif defined AG3
#define WHITEAG3
#define BLACKAG3

#elif defined AGB
#define WHITEAG2
#define BLACKAG2

#elif defined AG4
#define WHITEAG4
#define BLACKAG4
#endif
/************************* parameters for Opening Book *********************************/
#define BOOKBITS 10		/* # bits for hashtable to book moves */
#define BOOKFAIL 20000		/* if no book move found for BOOKFAIL turns stop using book */
#define BOOKRAND 1000		/* used to select an opening move from a list */
#define BOOKENDPCT 500		/* 50 % chance a BOOKEND will stop the book */
#define DONTUSE -32768		/* flag move as don't use */
/*************************** Book access defines ****************************************/
#define BKTBLSIZE (2<<BOOKBITS)
#define BOOKMASK (BKTBLSIZE - 1)
#define SIDEMASK 0x1
#define BOOKEND 0x2		/* means this is the last move of an opening */
#define BADMOVE 0x8000		/* means this is a bad move in this position */
/****************************************************************************************/
     struct hashval
     {
       unsigned long key, bd;
     };
     struct hashentry
     {
       unsigned long hashbd;
       unsigned short mv;
       unsigned char flags, depth;	/* char saves some space */
       short score;
#ifdef HASHTEST
       unsigned char bd[32];
#endif /* HASHTEST */

     };

#ifdef HASHFILE

/*
 * persistent transposition table. The size must be a power of 2. If you
 * change the size, be sure to run gnuchess -c before anything else.
 */
#define frehash 6
#ifdef MSDOS
#define Deffilesz (1 << 13) -1
#else
#define Deffilesz (1 << 17) -1
#endif /* MSDOS */
     struct fileentry
     {
       unsigned char bd[32];
       unsigned char f, t, flags, depth, sh, sl;
     };

#endif /* HASHFILE */


     struct leaf
     {
       short f, t, score, reply, width;
       unsigned short flags;
     };
     struct GameRec
     {
       unsigned short gmove;	/* this move */
       short score;		/* score after this move */
       short depth;		/* search depth this move */
       short piece;		/* piece captured */
       short color;		/* color */
       short flags;		/* move flags capture, promote, castle */
       short Game50;		/* flag for repetition */
       int time;		/* search time this move */
       long nodes;		/* nodes searched for this move */
       long hashkey, hashbd;	/* board key before this move */
#ifdef DEBUG40
       int d1;
       int d2;
       int d3;
       int d4;
       int d5;
       int d6;
       int d7;
#endif
     };
     struct TimeControlRec
     {
       short moves[2];
       long clock[2];
     };

     struct flags
     {
       short mate;		/* the game is over */
       short post;		/* show principle variation */
       short quit;		/* quit/exit */
       short regularstart;	/* did the game start from standard
				 * initial board ? */
       short reverse;		/* reverse board display */
       short bothsides;		/* computer plays both sides */
       short hash;		/* enable/disable transposition table */
       short force;		/* enter moves */
       short easy;		/* disable thinking on opponents time */
       short beep;		/* enable/disable beep */
       short timeout;		/* time to make a move */
       short musttimeout;	/* time to make a move */
       short rcptr;		/* enable/disable recapture heuristics */
       short rv;		/* reverse video */
       short stars;		/* add stars to uxdsp screen */
       short coords;		/* add coords to visual screen */
       short shade;
       short material;		/* draw on lack of material */
       short illegal;		/* illegal position */
       short onemove;		/* timing is onemove */
     };

#ifdef DEBUG
     extern FILE *debugfile;

#endif /* DEBUG */
#ifdef HISTORY
     extern unsigned char __far history[32768];
#endif
     extern char *ColorStr[2];
     extern unsigned short int MV[MAXDEPTH];
     extern int MSCORE;
     extern int mycnt1, mycnt2;
     extern short int ahead;
     extern short int chesstool;
     extern struct leaf Tree[], *root, rootnode;
     extern char savefile[], listfile[];
     extern short TrPnt[];
     extern short board[], color[];
     extern short PieceList[2][64], PawnCnt[2][8];
     extern short castld[], Mvboard[];
     extern short svalue[];
     extern struct flags flag;
     extern short opponent, computer, INCscore;
     extern short WAwindow, BAwindow, WBwindow, BBwindow;
     extern short dither, player;
     extern short xwndw, epsquare, contempt;
     extern long ResponseTime, ExtraTime, MaxResponseTime, et, et0, time0, ft;
     extern long reminus, replus;
     extern long NodeCnt, ETnodes, EvalNodes, HashAdd, HashCnt, HashCol, THashCol,
      FHashCnt, FHashAdd;
     extern short HashDepth, HashMoveLimit;
     extern struct GameRec __far GameList[];
     extern short GameCnt, Game50;
     extern short Sdepth, MaxSearchDepth;
     extern int Book;
     extern struct TimeControlRec TimeControl;
     extern short TCflag, TCmoves, TCminutes, TCseconds, OperatorTime;
     extern short XCmore, XCmoves[], XCminutes[], XCseconds[], XC;
     extern const short otherside[];
     extern const short Stboard[];
     extern const short Stcolor[];
     extern unsigned short hint;
     extern short int TOflag;
     extern short stage, stage2, Developed[];
     extern short ChkFlag[], CptrFlag[], PawnThreat[];
     extern short Pscore[], Tscore[];
     extern short rehash;
     extern unsigned int ttblsize;
     extern short mtl[], pmtl[], hung[], emtl[];
     extern short Pindex[];
     extern short PieceCnt[];
     extern short FROMsquare, TOsquare;
     extern short HasKnight[], HasBishop[], HasRook[], HasQueen[];
     extern const short qrook[];
     extern const short krook[];
     extern const short kingP[];
     extern const short rank7[];
     extern const short sweep[];
     extern const short epmove1[], epmove2[];
     extern unsigned short killr0[], killr1[];
     extern unsigned short killr2[], killr3[];
     extern unsigned short PV, SwagHt, Swag0, Swag1, Swag2, Swag3, Swag4, sidebit;
     extern short __far killt[0x4000];
     extern short mtl[2], pmtl[2], hung[2];
     extern const short value[];
     extern const short control[];
     extern unsigned char __far nextpos[8][64][64];
     extern unsigned char __far nextdir[8][64][64];
     extern const short ptype[2][8];
     extern long filesz;
     extern FILE *hashfile;
     extern unsigned int starttime;
     extern short distdata[64][64], taxidata[64][64];
     extern int bookcount;
     extern unsigned long hashkey, hashbd;
     extern struct hashval hashcode[2][7][64];
     extern char *CP[];
#ifdef QUIETBACKGROUND
     extern short background;
#endif /* QUIETBACKGROUND */

#ifdef ttblsz
     extern struct hashentry huge ttable[2][vttblsz + MAXrehash];

#endif

/*
 * hashbd contains a 32 bit "signature" of the board position. hashkey
 * contains a 16 bit code used to address the hash table. When a move is
 * made, XOR'ing the hashcode of moved piece on the from and to squares with
 * the hashbd and hashkey values keeps things current.
 */
#define UpdateHashbd(side, piece, f, t) \
{\
  if ((f) >= 0)\
    {\
      hashbd ^= hashcode[side][piece][f].bd;\
      hashkey ^= hashcode[side][piece][f].key;\
    }\
  if ((t) >= 0)\
    {\
      hashbd ^= hashcode[side][piece][t].bd;\
      hashkey ^= hashcode[side][piece][t].key;\
    }\
}


     extern short rpthash[2][256];
     extern char *DRAW;

#define distance(a,b) distdata[a][b]
#define row(a) ((a) >> 3)
#define column(a) ((a) & 7)
#define locn(a,b) (((a) << 3) | (b))
     extern short distdata[64][64];

/* init external functions */
     extern void NewGame (void);
     extern int parse (FILE * fd, unsigned short *mv, short side, char *opening);
     extern void GetOpenings (void);
     extern int OpeningBook (unsigned short int *hint, short int side);
     extern void SelectMove (short int side, short int iop);
     extern short
      search (short int side,
	       short int ply,
	       short int depth,
	       short int alpha,
	       short int beta,
	       unsigned short *bstline,
	       short int *rpt);
#if ttblsz
     extern int
      ProbeTTable (short int side,
		    short int depth,
		    short int ply,
		    short int *alpha,
		    short int *beta,
		    short int *score);
     extern int
      PutInTTable (short int side,
		    short int score,
		    short int depth,
		    short int ply,
		    short int alpha,
		    short int beta,
		    unsigned short mv);
     extern void ZeroTTable (void);
     extern void ZeroRPT (void);
     extern void Initialize_ttable (void);
#ifdef HASHFILE
     extern unsigned int urand (void);
     extern void srand (unsigned int);
     extern int
      ProbeFTable (short int side,
		    short int depth,
		    short int ply,
		    short int *alpha,
		    short int *beta,
		    short int *score);
     extern void
      PutInFTable (short int side,
		    short int score,
		    short int depth,
		    short int ply,
		    short int alpha,
		    short int beta,
		    unsigned short int f,
		    unsigned short  int t);

#endif /* HASHFILE */
#endif /* ttblsz */
     extern void Initialize_moves (void);
     extern void MoveList (short int side, short int ply);
     extern void CaptureList (short int side, short int ply);
     extern int castle (short int side, short int kf, short int kt, short int iop);
     extern void
      MakeMove (short int side,
		 struct leaf * node,
		 short int *tempb,
		 short int *tempc,
		 short int *tempsf,
		 short int *tempst,
		 short int *INCscore);
     extern void
      UnmakeMove (short int side,
		   struct leaf * node,
		   short int *tempb,
		   short int *tempc,
		   short int *tempsf,
		   short int *tempst);
     extern void InitializeStats (void);
     extern short
      evaluate (short int side,
		 short int ply,
		 short int alpha,
		 short int beta,
		 short int INCscore,
		 short int *slk,
		 short int *InChk);
     extern short int ScorePosition (short int side);
     extern void ExaminePosition (void);
     extern void UpdateWeights (void);
     extern void Initialize (void);
     extern void InputCommand (void);
     extern void ExitChess (void);
     extern void ClrScreen (void);
     extern void SetTimeControl (void);
     extern void SelectLevel (void);
     extern void
      UpdateDisplay (short int f,
		      short int t,
		      short int flag,
		      short int iscastle);
     extern void ElapsedTime (short int iop);
     extern void ShowSidetoMove (void);
     extern void SearchStartStuff (short int side);
     extern void ShowDepth (char ch);
     extern void TerminateSearch (int);
     extern void
      ShowResults (short int score,
		    unsigned short  int *bstline,
		    char ch);
     extern void PromptForMove (void);
     extern void SetupBoard (void);
     extern void algbr (short int f, short int t, short int flag);
     extern void OutputMove (void);
     extern void ShowCurrentMove (short int pnt, short int f, short int t);
     extern void ListGame (void);
     extern void ShowMessage (char *s);
     extern void ClrScreen (void);
     extern void gotoXY (short int x, short int y);
     extern void ClrEoln (void);
     extern void DrawPiece (short int sq);
     extern void UpdateClocks (void);
     extern void ShowLine (unsigned short  int *bstline);
     extern void pick (short int p1, short int p2);
     extern int TrComp (struct leaf * a, struct leaf * b);


/* some more protos */
#ifdef AMIGA
void ataks (short int side, short int *a);
unsigned int urand(void);
void srand(unsigned int seed);
#endif
