
/*----------------------------------------------------------------------
 | CONST                                                     940420
 |
 | Contains all constant definitions.
 +----------------------------------------------------------------------*/


#undef Debug

#ifdef WINDOWS
#define huge
#define far
#endif

#ifndef _WIN32
#include <stdio.h>
#include <limits.h>
#define ULONG_MAX 4294967295UL
#endif

typedef signed char     Signed1;
typedef unsigned char   Unsigned1;
typedef signed short    Signed2;
typedef unsigned short  Unsigned2;
typedef signed long     Signed4;
typedef unsigned long   Unsigned4;


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <math.h>


/* defaults */
#define DepthDefault            32
#define ColorDefault            Black
#define TransTableDefault       1
#define RefTableDefault         1
#define TwoLevelTableDefault    1 
#define TtValueDefault          1  
#define TtMoveDefault           1  
#define TimeStampDefault        1
#define UseFlagDefault          1    
#define TtBitsDefault           19   /* (default (19) 31mb hash) */
#define KeepPlyDefault          720  /* how many ply before hash is cleared */


/*

   b0   b1 b2 b3 b4 b5 b6 b7 b8   b9 ba bb bc bd be bf
   a0   a1 a2 a3 a4 a5 a6 a7 a8   a9 aa ab ac ad ae af
   +-------------------------+
   90 | A8 B8 C8 D8 E8 F8 G8 H8 | 99 9a 9b 9c 9d 9e 9f
   80 | A7 B7 C7 D7 E7 F7 G7 H7 | 89 8a 8b 8c 8d 8e 8f
   70 | A6 B6 C6 D6 E6 F6 G6 H6 | 79 7a 7b 7c 7d 7e 7f
   60 | A5 B5 C5 D5 E5 F5 G5 H5 | 69 6a 6b 6c 6d 6e 6f
   50 | A4 B4 C4 D4 E4 F4 G4 H4 | 59 5a 5b 5c 5d 5e 5f
   40 | A3 B3 C3 D3 E3 F3 G3 H3 | 49 4a 4b 4c 4d 4e 4f
   30 | A2 B2 C2 D2 E2 F2 G2 H2 | 39 3a 3b 3c 3d 3e 3f
   20 | A1 B1 C1 D1 E1 F1 G1 H1 | 29 2a 2b 2c 2d 2e 2f
   +-------------------------+
   10   11 12 13 14 15 16 17 18   19 1a 1b 1c 1d 1e 1f
   00   01 02 03 04 05 06 07 08   09 0a 0b 0c 0d 0e 0f
 */

#define BoardLength     16      /* Power of 2 because of dividing by Length */
#define NrSquares       (BoardLength*12)

/* Squares */
#define A1      (2*BoardLength+1)
#define B1      (A1+1)
#define C1      (B1+1)
#define D1      (C1+1)
#define E1      (D1+1)
#define F1      (E1+1)
#define G1      (F1+1)
#define H1      (G1+1)
#define A2      (A1+BoardLength)
#define B2      (A2+1)
#define C2      (B2+1)
#define D2      (C2+1)
#define E2      (D2+1)
#define F2      (E2+1)
#define G2      (F2+1)
#define H2      (G2+1)
#define A3      (A2+BoardLength)
#define B3      (A3+1)
#define C3      (B3+1)
#define D3      (C3+1)
#define E3      (D3+1)
#define F3      (E3+1)
#define G3      (F3+1)
#define H3      (G3+1)
#define A4      (A3+BoardLength)
#define B4      (A4+1)
#define C4      (B4+1)
#define D4      (C4+1)
#define E4      (D4+1)
#define F4      (E4+1)
#define G4      (F4+1)
#define H4      (G4+1)
#define A5      (A4+BoardLength)
#define B5      (A5+1)
#define C5      (B5+1)
#define D5      (C5+1)
#define E5      (D5+1)
#define F5      (E5+1)
#define G5      (F5+1)
#define H5      (G5+1)
#define A6      (A5+BoardLength)
#define B6      (A6+1)
#define C6      (B6+1)
#define D6      (C6+1)
#define E6      (D6+1)
#define F6      (E6+1)
#define G6      (F6+1)
#define H6      (G6+1)
#define A7      (A6+BoardLength)
#define B7      (A7+1)
#define C7      (B7+1)
#define D7      (C7+1)
#define E7      (D7+1)
#define F7      (E7+1)
#define G7      (F7+1)
#define H7      (G7+1)
#define A8      (A7+BoardLength)
#define B8      (A8+1)
#define C8      (B8+1)
#define D8      (C8+1)
#define E8      (D8+1)
#define F8      (E8+1)
#define G8      (F8+1)
#define H8      (G8+1)

/* Files */
#define A       1
#define B       2
#define C       3
#define D       4
#define E       5
#define F       6
#define G       7
#define H       8

/* Contents of squares */
#define Empty   0

#define Black   0
#define White   1

#define Pawn    2
#define Knight  4
#define Bishop  8
#define Rook    16
#define Queen   32
#define King    64

#define Edge    128

#define WhitePawn   (White | Pawn)
#define WhiteKnight (White | Knight)
#define WhiteBishop (White | Bishop)
#define WhiteRook   (White | Rook)
#define WhiteQueen  (White | Queen)
#define WhiteKing   (White | King)

#define BlackPawn   (Black | Pawn)
#define BlackKnight (Black | Knight)
#define BlackBishop (Black | Bishop)
#define BlackRook   (Black | Rook)
#define BlackQueen  (Black | Queen)
#define BlackKing   (Black | King)

#define MaxKnightMoves  8
#define MaxBishopMoves  13
#define MaxRookMoves    14

#define MaxMoves        200     /* Maximum number of moves in a position */ // was 200


#define Up      BoardLength
#define Down    (-BoardLength)
#define Right   1
#define Left    (-1)

/* Move types */
#define Normal          0
#define Double          1
#define ShortCastle     2
#define LongCastle      4
#define EnPassant       8
#define Capture         16
#define Promotion       32

#define NoEp            1       /* Not 0 because of 0s in move tables */

#define MaxCommandLength        256

#define Ever    ;;

/* Commands */
#define Quit            0
#define Help            1
#define Move            2
#define PrintB          3
#define List            4
#define Forward         5
#define Back            6
#define NewG            7
#define PrintG          8
#define Compute         9
#define Save            10
#define Load            11
#define Clear           12
#define Place           13
#define Remove          14
#define SavePos         15
#define Test            16
#define xboard          17
#define go              18
#define protover        19
#define new             20
#define easy            23
#define hard            24
#define MaxCommands     25

#define MaxGamePlies    1000

static int MaxSearchDepth = 80;

#define MaxMoveLength           8     // was 8
#define MaxFileNameLength      250     // was 80

/* Possible castlings */
#define WhiteShort      1
#define WhiteLong       2
#define BlackShort      4
#define BlackLong       8

/* Castle indices used for castlingHashTable */
#define Short           0
#define Long            1

#ifdef UNIX
#define GameDirectory   "games/"
#else
#define GameDirectory   "games\\"
#endif

/* Evaluation values */
#define Mate            10000
#define Draw            0
#define Infinity        16000
#define MateValue       (Mate-100)


#define EndgameMaterial 5000    /* 1800+3200 */ 

/* flag for transposition table */
#define NoEntry         0
#define Valid           1
#define UpperBound      2
#define LowerBound      3

/* Keep methods in case of collision */
#define New             0
#define Old             1
#define Deep            2
#define Big1            3
#define BigAll          4

/* Pack constants for transposition tables */
#define PackKnight      0
#define PackBishop      1
#define PackRook        2
#define PackQueen       3

#define PackNormal              0
#define PackDouble              1
#define PackShortCastle         2
#define PackLongCastle          3
#define PackEnPassant           4
#define PackCapture             5
#define PackPromotion           6
#define PackCapPromotion        7

#define StartPositionHash       ((0x34L<<24) | (0x17L<<16) | (0xa3L<<8) | 0xe6L)



/*----------------------------------------------------------------------
 | TYPE							940420
 |
 | Contains all type definitions.
 +----------------------------------------------------------------------*/




typedef Unsigned1 Boolean;
typedef Signed2 ValueType;

typedef Unsigned1 SquareType;   /* Needs at least 8 bits */
typedef Unsigned2 BoardIndexType;
typedef Signed2 DirectionType;

typedef Unsigned4 HashType[2];

typedef struct _CheckPieceType {
    BoardIndexType  square;
    DirectionType   dir;
}
                CheckPieceType;

typedef struct _PieceType {
    BoardIndexType  square;
    SquareType      type;
}
                PieceType;

typedef struct _MoveType {
    BoardIndexType  from,
                    to;
    SquareType      capturedPiece;
    SquareType      promotionPiece;
    Unsigned1       type;
}
                MoveType;

typedef struct _PathType {
    char            moveString[MaxMoveLength];
    MoveType        move;
    struct _PathType *next;
}
                PathType;

typedef struct _History {
    BoardIndexType  from,
                    to;
    Unsigned2       nr;
}
                History;

typedef struct _TtEntry {
    Unsigned4       lockPlyDepthFlag;
    Unsigned4       lockRemainder;
    Unsigned4       fromToPromTypeVal;
    Unsigned4       nrNodes;
    Unsigned1       ply;
}
                TtEntry;




/*----------------------------------------------------------------------
 | MACRO						940420
 |
 | Contains all macro-definitions.
 +----------------------------------------------------------------------*/




/* SquareType macros */
#define	IsEmpty( square )	(!(square))
#define	IsEdge( square )	((square) & Edge)
#define	IsWhite( piece )	((piece) & White)
#define IsBlack( piece )	(!IsWhite( piece ))
#define IsColor( piece, color )	\
  (color == White ? IsWhite( piece) : IsBlack( piece ))
#define	IsPawn( piece )		((piece) & Pawn)
#define	IsKnight( piece )	((piece) & Knight)
#define	IsBishop( piece )	((piece) & Bishop)
#define	IsRook( piece )		((piece) & Rook)
#define	IsQueen( piece )	((piece) & Queen)
#define	IsKing( piece )		((piece) & King)
#define Color( piece )		((piece) & White)

/* MoveType macros */
#define IsCaptureMove( type )	((type) & Capture)
#define IsEnPassantMove( type )	((type) & EnPassant)
#define IsPromotionMove( type )	((type) & Promotion)
#define IsDoubleMove( type )	((type) & Double)
#define IsShortCastleMove( type )	((type) & ShortCastle)
#define IsLongCastleMove( type )	((type) & LongCastle)

#define WhiteSquare( file, rank )	((file-A+rank-1)%2)

#define	MovesDiagonal( piece )	((piece) & (Bishop | Queen))
#define	MovesStraight( piece )	((piece) & (Rook | Queen))

#define	Square( file, rank )	(((rank)+1)*BoardLength + (file))
#define Rank( square )		((square)/BoardLength - 1)
#define File( square )		((square)%BoardLength)
#define OnSeventhRank( color, square ) \
	(Rank( square ) == (IsWhite( color ) ? 7 : 2))

#define IsCheckingDir( direction )	      \
	(checkingPiece[ 0 ].dir==direction || \
		checkingPiece[ 1 ].dir==direction)

/* Castling */
#define ShortCastlingPossible()					\
	(toMove==White ? (castling[ nrGamePlies ] & WhiteShort)	\
		: (castling[ nrGamePlies ] & BlackShort))

#define LongCastlingPossible()					\
	(toMove==White ? (castling[ nrGamePlies ] & WhiteLong)	\
		: (castling[ nrGamePlies ] & BlackLong))

/*
   #define NoCastling()               \
   castling[ nrGamePlies ] &= \
   toMove==White ? (BlackLong | BlackShort) : (WhiteLong | WhiteShort)
 */

#define NoShortCastling()          \
	castling[ nrGamePlies ] &= \
		toMove==White ? ~WhiteShort : ~BlackShort

#define NoLongCastling()           \
	castling[ nrGamePlies ] &= \
		toMove==White ? ~WhiteLong : ~BlackLong

#define GetEvalTable( table, color, piece )				\
        if (IsPawn( piece )) {						\
          table = pawnEvalTable[ color ];				\
        } else if (IsKnight( piece )) {					\
          table = knightEvalTable[ color ];				\
        } else if (IsBishop( piece )) {					\
          table = bishopEvalTable[ color ];				\
        } else if (IsRook( piece )) {					\
          table = rookEvalTable[ color ];				\
        } else if (IsQueen( piece )) {					\
          table = queenEvalTable[ color ];				\
        } else if (IsKing( piece )) {					\
          table = kingEvalTable[ color ];				\
	} else {							\
	  printf( "ERROR: wrong piece %d in GetEvalTable\n", piece );	\
	}

#define GetHashTable( table, color, piece ) 				\
        if (IsPawn( piece )) {              				\
          table = pawnHashTable[ color ];   				\
        } else if (IsKnight( piece )) {     				\
          table = knightHashTable[ color ]; 				\
        } else if (IsBishop( piece )) {     				\
          table = bishopHashTable[ color ]; 				\
        } else if (IsRook( piece )) {       				\
          table = rookHashTable[ color ];   				\
        } else if (IsQueen( piece )) {      				\
          table = queenHashTable[ color ];  				\
        } else if (IsKing( piece )) {       				\
          table = kingHashTable[ color ];   				\
	} else {							\
	  printf( "ERROR: wrong piece %d in GetHashTable\n", piece );	\
	}

#define SPrintSquare( s, square ) \
	sprintf( s, "%c%d", File( square )-A+'a', Rank( square ) )

#define SPrintMove( s, move ) 			  	       	       \
	if (computer == toMove) symbolType[0] = 'x'; \
	if (computer != toMove) symbolType[0] = '-'; \
	if (force_mode) symbolType[0] = '-'; \
    if (IsShortCastleMove( (move).type ) && computer == toMove) {                    \
	  sprintf( s, "  0-0  " );                                     \
    } else if (IsLongCastleMove( (move).type ) && computer == toMove) {     \
	  sprintf( s, " 0-0-0 " );                                           \
	} else if (IsShortCastleMove( (move).type ) && computer == Black) {                \
	  sprintf( s, " e1-g1 " );                                     \
	} else if (IsShortCastleMove( (move).type ) && computer == White) {                \
	  sprintf( s, " e8-g8 " );                                     \
    } else if (IsLongCastleMove( (move).type ) && computer == White) {                  \
	  sprintf( s, " e8-c8 " );                                     \
	} else if (IsLongCastleMove( (move).type ) && computer == Black) {                  \
	  sprintf( s, " e1-c1 " );                                     \
    } else {                                                       \
	    sprintf( s, "%c%c%d%c%c%d%c",                                \
		IsPawn( board[ (move).from ] ) ? ' '		       \
			: pieceSymbol[ board[ (move).from ] | White ], \
		File( (move).from )-A+'a', Rank( (move).from ),        \
		(move).capturedPiece ? symbolType[0] : '-',                      \
		File( (move).to )-A+'a', Rank( (move).to ),            \
		(move).promotionPiece                                  \
			? pieceSymbol[ (move).promotionPiece | White ] \
			: ' ' );				       \
	}

#ifdef Debug
#define PutMoveInTable( mFrom, mTo, mCapturedPiece, mPromotionPiece, \
			mType, mList, mNr ) 			     \
	{ 					 	   	     \
	  MoveType	*move; 			 	  	     \
	  move = &(mList[ mNr ]); 		          	     \
	  move->from = mFrom; 			 	  	     \
	  move->to = mTo;			       	 	     \
	  move->capturedPiece = mCapturedPiece;		  	     \
	  move->promotionPiece = mPromotionPiece;		     \
	  move->type = mType;				 	     \
	  ++mNr;						     \
	  if ((IsCaptureMove( mType ) && !(mCapturedPiece)) ||         \
		(!IsCaptureMove( mType ) && (mCapturedPiece))) {       \
	    printf( "ERROR: strange capture move (%d %d)\n",	     \
		mType, mCapturedPiece );               		     \
	  }                                                          \
	}
#else
#define PutMoveInTable( mFrom, mTo, mCapturedPiece, mPromotionPiece, \
			mType, mList, mNr ) 			     \
	{ 					 	   	     \
	  MoveType	*move; 			 	  	     \
	  move = &(mList[ mNr ]); 		          	     \
	  move->from = mFrom; 			 	  	     \
	  move->to = mTo;			       	 	     \
	  move->capturedPiece = mCapturedPiece;		  	     \
	  move->promotionPiece = mPromotionPiece;		     \
	  move->type = mType;				 	     \
	  ++mNr;						     \
	}
#endif

/* Allocation routines */
#define Malloc( ptr, type, nr )				    \
	{						    \
	  if (nr > 0) {					    \
	    ptr = (type *) malloc( (nr) * sizeof( type ) ); \
	    if (ptr == (type *) NULL) {			    \
	      printf( "ERROR: malloc van ptr mislukt\n" );  \
	      exit( 0 );				    \
	    }						    \
	  }						    \
	}

#define AllocateMoveList( list, nr )	\
	{				\
	  Malloc( list, MoveType, nr );	\
	  nrAllocMoveLists++;		\
	}

#define FreeMoveList( list )  \
	{		      \
	  free( list );	      \
	  nrAllocMoveLists--; \
	}

#define AllocatePathMove( path )       \
	{                              \
	  Malloc( path, PathType, 1 ); \
	  (path)->next = NULL;         \
	  nrAllocPathMoves++;          \
	}


#define FileExists( name )	(fopen( name, "r" )==NULL ? false : true)

#define SkipSpaces( ptr )	while (*(ptr)==' ') (ptr)++

/* time macro's */

#ifdef UNIX
#define StartTime()                                                   \
	{                                                             \
	  struct tms	mT;                                           \
	  times( &mT );                                               \
	  startingTime = (double) (mT.tms_utime + mT.tms_stime) / HZ; \
	}

#define StopTime( timeUsed )                                                \
	{                                                                   \
	  struct tms	mT;                                                 \
	  times( &mT );                                                     \
	  timeUsed = (double)(mT.tms_utime + mT.tms_stime)/HZ-startingTime; \
	}
#else
#define StartTime()                                   \
	{                                             \
	  struct timeb	mT;                           \
	  ftime( &mT );                               \
	  startingTime = mT.time + mT.millitm/1000.0; \
	}

#define StopTime( timeUsed )                                     \
	{                                                        \
	  struct timeb	mT;                                      \
	  ftime( &mT );                                          \
	  timeUsed = mT.time + mT.millitm/1000.0 - startingTime; \
	}
#endif

/* value macro's */
#define PrintValue( value )						      \
        (value) >= MateValue ? printf( " Mate%02d ", ((Mate-(value))+1)/2 ) : \
        (value) <= -MateValue ? printf( "-Mate%02d ", (Mate+value)/2 ) :      \
         printf( "%9d ", value)
/* hash macro's */
#define HashMakeZero( var ) \
	var[ 0 ] = var[ 1 ] = 0

#define HashXorIs( dest, src ) \
	{ dest[ 0 ] ^= src[ 0 ]; dest[ 1 ] ^= src[ 1 ]; }


#define SetRandomHash( var )                    \
	{                                       \
          while ((var[ 0 ] = drand48()*ULONG_MAX) == 0) ; \
          while ((var[ 1 ] = drand48()*ULONG_MAX) == 0) ; \
	}

#define HashIs( dest, src ) \
	{ dest[ 0 ] = src[ 0 ]; dest[ 1 ] = src[ 1 ]; }

#define HashEqual( hash1, hash2 ) \
	(hash1[ 0 ]==hash2[ 0 ] && hash1[ 1 ]==hash2[ 1 ])

#define EqualMoves( move1, move2 )                                       \
	((move1)->from == (move2)->from && (move1)->to == (move2)->to && \
	 (move1)->capturedPiece == (move2)->capturedPiece &&             \
	 (move1)->promotionPiece == (move2)->promotionPiece &&           \
	 (move1)->type == (move2)->type)



 

#define PrintSearchInfo_ICS( depth, value, timeUsed, path )	\
	{						\
	if (depth > mymaxdepth) { \
      StopTime( timeUsed );				\
	  if (depth > 0 && depth <32) {				\
 	 mymaxdepth = depth; \
	  } \
      if (depth > 0 && depth <32) {				\
 	 printf( "tellics whisper kibitz %2d ", depth );			\
  	} else {					\
      printf( "tellics whisper kibitz %2d ", mymaxdepth );			\
	  }						\
	  printf( "tellics whisper kibitz %d ", value); \
      printf( "tellics whisper kibitz %d ", (int) (100 * timeUsed) ); \
      printf( "tellics whisper kibitz %lu ", nrTotalNodes); \
	  PrintPath( path );				\
	  printf( "\n" );				\
	  mymaxdepth = 0; \
	 }\
	}


#define PrintSearchInfo( depth, value, timeUsed, path )	\
	{						\
	if (post && depth > mymaxdepth) { \
      StopTime( timeUsed );				\
	  if (depth > 0 && depth <32) {				\
 	 mymaxdepth = depth; \
	  } \
      if (depth > 0 && depth <32) {				\
 	 printf( "%2d ", depth );			\
  	} else {					\
      printf( "%2d ", mymaxdepth );			\
	  }						\
	  printf( "%d ", value); \
      printf( "%d ", (int) (100 * timeUsed) ); \
      printf( "%lu ", nrTotalNodes); \
	  PrintPath( path );				\
	  printf( "\n" );				\
	  mymaxdepth = 0; \
	 }\
	}




#define PrintSearchInfo_edit( depth, value, timeUsed, path, shortmate )	\
	{						\
	if (post && depth > mymaxdepth) { \
      StopTime( timeUsed );				\
	  if (depth > 0 && depth <32) {				\
 	 mymaxdepth = depth; \
	  } \
      if (depth > 0 && depth <32) {				\
 	 printf( "%2d ", depth );			\
  	} else {					\
      printf( "%2d ", mymaxdepth );			\
	  }						\
	  printf( "%d ", value); \
      printf( "%d ", (int) (100 * timeUsed) ); \
      printf( "%lu ", nrTotalNodes); \
	  PrintPath( path );				\
	  printf(" (%s)", shortmate); \
	  printf( "\n" );				\
	  mymaxdepth = 0; \
	 }\
	}



/* transposition table macro's */
//#define GetPly( entry ) \
//	((entry)->ply)

// VOOR 1024K
   #define GetPly( entry ) \
   (((entry)->lockPlyDepthFlag & ((1L<<15)-1)) >> 7)
 

#define GetDepth( entry ) \
	(((entry)->lockPlyDepthFlag & ((1L<<7)-1)) >> 2)

#define GetFlag( entry ) \
	((entry)->lockPlyDepthFlag & ((1L<<2)-1))

#define GetFrom( entry ) \
	((entry)->fromToPromTypeVal >> 26)

#define GetTo( entry ) \
	(((entry)->fromToPromTypeVal & ((1L<<26)-1)) >> 20)

#define GetPiece( entry ) \
	(((entry)->fromToPromTypeVal & ((1L<<20)-1)) >> 18)

#define GetType( entry ) \
	(((entry)->fromToPromTypeVal & ((1L<<18)-1)) >> 15)

#define GetValue( entry ) \
	(((entry)->fromToPromTypeVal & ((1L<<15)-1)) - Infinity)

#define ClearEntry( entry )	(entry)->lockPlyDepthFlag = NoEntry

#define SamePosition( entry )						\
	((entry)->lockRemainder==hashValue[ nrGamePlies ][ 1 ] &&	\
		((entry)->lockPlyDepthFlag>>nrTtBits) ==		\
		(hashValue[ nrGamePlies ][ 0 ]>>nrTtBits))

#define ComposeMove( entry, ttMove )					\
	{								\
	  (ttMove).from = unpackSquare[ GetFrom( entry ) ];		\
	  (ttMove).to   = unpackSquare[ GetTo( entry ) ];		\
	  (ttMove).type = unpackType[ GetType( entry ) ];		\
	  (ttMove).promotionPiece = IsPromotionMove( (ttMove).type ) ?	\
		unpackPiece[ GetPiece( entry ) ] | toMove : 0;		\
          if (IsCaptureMove( (ttMove).type )) {				\
	    if (IsEnPassantMove( (ttMove).type )) {			\
	      ttMove.capturedPiece = Pawn | !toMove;			\
	    } else {							\
	      ttMove.capturedPiece = board[ (ttMove).to ];		\
	    }								\
	  } else {							\
	    ttMove.capturedPiece = 0;					\
	  }								\
	}

#define FillEntry( mTtEntry, ttDepth, ttFlag, ttMove, ttValue, ttNodes )  \
	{								  \
	  Signed1 mDepth;						  \
	  if (ttDepth > 31) {						  \
	    mDepth = 31;						  \
	  } else {							  \
	    mDepth = ttDepth;						  \
	  }								  \
	    /* lock is 49 bits -> ttBits >= 15 */			  \
	    /* ply is 8 bits: max. = 255 */				  \
	    /* depth is 5 bits: max = 31 */				  \
	    /* flag is 2 bits: Lower, Upper, Valid and NoEntry */	  \
	  mTtEntry->lockPlyDepthFlag =					  \
		(hashValue[ nrGamePlies ][ 0 ] & ~((1L<<nrTtBits)-1)) |	  \
		(mDepth)<<2 | (ttFlag);					  \
/*\
		startPly<<7 | (mDepth)<<2 | (ttFlag);			  \
*/\
	  mTtEntry->lockRemainder = hashValue[ nrGamePlies ][ 1 ];	  \
	    /* promotionPiece is 2 bits */				  \
	    /* type is 3 bits */					  \
	    /* value is 15 bits: -16384..16384 */			  \
	  mTtEntry->fromToPromTypeVal = 				  \
		(Unsigned4)(packSquare[ (ttMove).from ])<<26 | 		  \
		(Unsigned4)(packSquare[ (ttMove).to ])<<20 |		  \
		(Unsigned4)(packPiece[ (ttMove).promotionPiece ])<<18 |	  \
		(Unsigned4)(packType[ (ttMove).type ])<<15 | (ttValue+Infinity);	  \
	  mTtEntry->nrNodes = ttNodes;					  \
          mTtEntry->ply = startPly;					  \
	}

#define PutMoveInTransTable( ttMove, ttDepth, ttValue, ttFlag, ttNodes )     \
	{								     \
	  Unsigned4	mIndex;						     \
	  TtEntry	*mTtEntry;					     \
	  ValueType	realValue;					     \
	  if (useTransTable) {						     \
	    nrWrites++;							     \
	    if (ttValue >= MateValue) {					     \
	      realValue = ttValue+nrGamePlies-startPly;			     \
            } else if (ttValue <= -MateValue) {				     \
	      realValue = ttValue-nrGamePlies+startPly;			     \
            } else {							     \
              realValue = ttValue;					     \
            }								     \
	    mIndex = hashValue[ nrGamePlies ][ 0 ] & ((1L<<nrTtBits)-1);     \
	    mTtEntry = &transTable[ mIndex ];				     \
	    if (GetFlag( mTtEntry )==NoEntry || SamePosition( mTtEntry )) {  \
              FillEntry( mTtEntry, ttDepth, ttFlag, ttMove,		     \
		ttValue, ttNodes );					     \
	    } else if (useTwoLevelTable) {				     \
	      if (timeStamp &&						     \
			GetPly( mTtEntry )+keepPly<startPly) { /* old */     \
		transTable[ mIndex+(1L<<nrTtBits) ] = transTable[ mIndex ];  \
		FillEntry( mTtEntry, ttDepth, ttFlag, ttMove,		     \
			ttValue, ttNodes );				     \
	      } else {							     \
		++nrCollisions;						     \
		if ((keepMethod==Deep && ttDepth>=GetDepth( mTtEntry )) ||   \
		  ((keepMethod==Big1 || keepMethod==BigAll) &&		     \
		  ttNodes>=mTtEntry->nrNodes)) {			     \
		    transTable[ mIndex+(1L<<nrTtBits) ] = transTable[ mIndex ];\
		    FillEntry( mTtEntry, ttDepth, ttFlag, ttMove,	     \
			  ttValue, ttNodes );				     \
		} else {						     \
		  mIndex += 1L<<nrTtBits;				     \
		  mTtEntry = &transTable[ mIndex ];			     \
		  FillEntry( mTtEntry, ttDepth, ttFlag, ttMove,		     \
			  ttValue, ttNodes );				     \
		}							     \
	      }								     \
	    } else if (timeStamp &&					     \
			GetPly( mTtEntry )+keepPly<startPly) { /* old */     \
	      FillEntry( mTtEntry, ttDepth, ttFlag, ttMove,		     \
		ttValue, ttNodes );					     \
            } else {							     \
	      ++nrCollisions;						     \
	      if ((useFlag && ttFlag==Valid && GetFlag( mTtEntry )!=Valid) ||\
		 keepMethod==New ||					     \
		(keepMethod==Deep && ttDepth>=GetDepth( mTtEntry )) ||       \
		((keepMethod==Big1 || keepMethod==BigAll) &&		     \
		ttNodes>=mTtEntry->nrNodes)) {				     \
		FillEntry( mTtEntry, ttDepth, ttFlag, ttMove,		     \
			ttValue, ttNodes );				     \
	      }								     \
	    }								     \
	  } /* if useTransTable */					     \
	}

#define GetMoveFromTransTable( ttMove, ttDepth, ttValue, ttFlag, ttNodes ) \
	{								   \
	  Unsigned4	mIndex;						   \
	  TtEntry	*mTtEntry;					   \
	  if (!useTransTable) {						   \
	    ttDepth = -1;						   \
	  } else {							   \
	    nrReads++;							   \
	    mIndex = hashValue[ nrGamePlies ][ 0 ] & ((1L<<nrTtBits)-1);   \
	    mTtEntry = &transTable[ mIndex ];				   \
	    if (GetFlag( mTtEntry ) != NoEntry) {			   \
	      if (SamePosition( mTtEntry )) {				   \
		nrHits++;						   \
		ComposeMove( mTtEntry, ttMove );			   \
		ttFlag = (Unsigned1) GetFlag( mTtEntry );		   \
		ttDepth = (Signed1) GetDepth( mTtEntry );		   \
		ttNodes = mTtEntry->nrNodes;				   \
		ttValue = (ValueType) GetValue( mTtEntry );		   \
		if (ttValue >= MateValue) {				   \
		  ttValue -= nrGamePlies-startPly;			   \
		} else if (ttValue <= -MateValue) {			   \
		  ttValue += nrGamePlies-startPly;			   \
		}							   \
              } else if (useTwoLevelTable) {                               \
		nrReads++;						   \
		mIndex += 1L<<nrTtBits;                                    \
                mTtEntry = &transTable[ mIndex ];                          \
                if (GetFlag( mTtEntry ) != NoEntry) {                      \
                  if (SamePosition( mTtEntry )) {                          \
                    nrHits++;                                              \
                    ComposeMove( mTtEntry, ttMove );                       \
                    ttFlag = (Unsigned1) GetFlag( mTtEntry );		   \
                    ttDepth = (Signed1) GetDepth( mTtEntry );		   \
		    ttNodes = mTtEntry->nrNodes;			   \
                    ttValue = (ValueType) GetValue( mTtEntry );            \
                    if (ttValue >= MateValue) {                            \
                      ttValue -= nrGamePlies-startPly;                     \
                    } else if (ttValue <= -MateValue) {                    \
                      ttValue += nrGamePlies-startPly;                     \
                    }                                                      \
                  } else {                                                 \
                    ttDepth = -1;                                          \
                  }                                                        \
                } else {                                                   \
                  ttDepth = -1;                                            \
                }                                                          \
              } else {                                                     \
                ttDepth = -1;                                              \
              }                                                            \
	    } else {							   \
	      ttDepth = -1;						   \
	    }								   \
	  }								   \
	}

#define IsIllegal( move )						\
	(IsEmpty( board[ (move).from ] ) ||				\
	!IsColor( board[ (move).from ], toMove ) ||			\
	((move).capturedPiece==0 && !IsEmpty( board[ (move).to ] )) ||	\
	((move).capturedPiece!=0 && IsEmpty( board[ (move).to ] ) &&	\
		!IsEnPassantMove( (move).type )) ||			\
	(!IsEmpty( board[ (move).to ] ) && IsColor( board[ (move).to ], toMove )))




/*----------------------------------------------------------------------
 | VAR							940420
 |
 | Contains all global procedure prototypes and variable prototypes.
 +----------------------------------------------------------------------*/



#define bool int
#define true 1
#define false 0


#define CDECL

static void CDECL catch_sigint(int s);

static void     CDECL
                catch_sigint(int s)
{
    signal(s, catch_sigint);
}



#define     VERSION         "1.19wb JA"
#define     BUILDDATE       "01-04-10"


#ifndef _MSC_VER
#ifndef INFINITY
#define INFINITY (1.0/0.0)
#endif
#define INFINITE INFINITY
#endif

#define INI_FILENAME "alibaba.ini"

static int MAX_TIME = 60;
static int Resign_value = 900;
static char black_string[3];
static char shortmate[265] = "--> Shortest mate found!";
static bool analyze_black = false;

/* piece values */


static int pawn_value    =   0;
static int knight_value  =   0;    
static int bishop_value  =   0;         
static int rook_value    =   0;
static int queen_value   =   0;
static int king_value    =   0; 

static int pawn_value_endgame       = 0;
static int knight_value_endgame     = 0;
static int bishop_value_endgame     = 0;
static int rook_value_endgame       = 0;
static int queen_value_endgame      = 0;
static int king_value_endgame       = 0;

static int white_pawns   = 0;
static int black_pawns   = 0;
static int white_knights = 0;
static int black_knights = 0;
static int white_bishops = 0;
static int black_bishops = 0;
static int white_rooks   = 0;
static int black_rooks   = 0;
static int white_queens  = 0;
static int black_queens  = 0;

static bool bishop_pair_bonus = true;
static bool bishop_pair_bonus_extra = false; 
static bool rook_pair_bonus = false;

static int total_piece_count = 0;
static bool insufficiant_material = false; 

static bool White_Bishop_Square_White = false;
static bool White_Bishop_Square_Black = false;
static bool Black_Bishop_Square_White = false;
static bool Black_Bishop_Square_Black = false;

static int use_insuf_draw = 0;
static int insuf_draw_use = 0;
static bool using_insufficient_draw = false;
static bool only_pawns_left = false;
static bool last_pawn = false;


static bool using_bookthinker  = false;
static bool using_resign       = false;
static bool using_draw_offer   = false;
static bool analyze_on         = false;
static bool shortest_mate      = false;
   
static int use_bookthinker  = 0;
static int bookthinker_use  = 0;
static int use_resign       = 0;
static int resign_score     = 0;
static int score_resign     = 0;
static int resign_count     = 0;
static int count_resign     = 3;
static int resign_use       = 1;
static int use_draw_offer   = 0;
static int draw_offer_use   = 1;
static int use_hashsize     = 0;
static int hashsize_use     = 0;
static int time_adjust      = 0;
static int adjust_time      = 0;

static int value_pawn       = 140;
static int value_knight     = 400;
static int value_bishop     = 400;
static int value_rook       = 600;
static int value_queen      = 1200;
static int value_king       = 3200;

static int bp_bonus       = 0; // used for bishop pair value increase
static int bp_bonus_extra = 0; // used for extra bishop pair value increase if queen down
static int rp_bonus       = 0; // used for rook pair value increase if queen down

static int endgame_value_pawn       = 160;
static int endgame_value_knight     = 440;
static int endgame_value_bishop     = 460;
static int endgame_value_rook       = 640;
static int endgame_value_queen      = 1200;
static int endgame_value_king       = 3200;

/* positional Bonuses */
static int castling_incentive = 0;
static int incentive_castling = 80;
static int incentive_capture  = 30;


static bool  xboard_mode          = false;
static bool  print_board          = false;
static bool  first_move           = false;
static bool  ftime_ok             = false;
static bool  st_time              = false;
static bool  time_set             = false;
static bool  force_mode           = false;
static bool  draw_offer           = false;
static bool  ENDGAME_REACHED      = false;
static bool  Stop_Search          = false;
static bool  post                 = true;
static bool  memory_on            = true;
static bool  icc                  = false;
static bool  edit_mode            = false;
static bool  new_used             = false;


static int   maxdepth             = 80;
static int   max_moves            = 40;
static int   minutes              = 0;
static int   secs                 = 0;
static int   milsecs              = 0;
static int   timeadd              = 0;
static int   add_time             = 0;
static int   move_count           = 0;
static int   resign_counter       = 0;
static int   mymaxdepth           = 0;
static int   memory               = 0;
static int   hashsize             = 0;
static int   show_hash_stats      = 0;
static int   hash_stats_show      = 0;
static int   depth                = 0;

static char  wb_command[256];
static char  line[256];

static int start_time         = 0;
static int maxtime            = 0;
static int inc_time           = 0;
static int stop_time          = 0;
static int time_left_opponent = 0;
static int time_left_computer = 0;

static ValueType       value;
static ValueType       myvalue;
static char symbolType[100];
static int KeyNum(char *key);
static int SetINIKey(char *key, char *buffer, bool default_val);

extern Unsigned1 nrTtBits;

static ValueType eval_score;

static MoveType BestMove;

static Signed2 IScore;

/* hash scheme keep method - 1=on 0=off (choose only one) */

static int Use_New       = 0;
static int Use_Big1      = 0;
static int Use_BigAll    = 0;
static int Use_Deep      = 0;
static int Use_Old       = 0;


static int new_use    = 1;
static int big1_use   = 0;
static int bigall_use = 0;
static int deep_use   = 0;
static int old_use    = 0;

/*
old:
    in case of a collision, the oldest position is kept in the table. Thus,
    a position is *never* overwritten.
  new:
    in case of a collision, the newest position is kept in the table. Thus,
    a position is *always* overwritten.
  deep:
    in case of a collision, the position with the deepest subtree is kept
    in the table
  big1:
    in case of a collision, the position with the biggest subtree (in terms
    of number of nodes) is kept in the table. A position read from the
    transposition table is counted as one node.
  bigAll:
    in case of a collision, the position with the biggest subtree (in terms
    of number of nodes) is kept in the table. A position read from the
    transposition table is counted as the number of nodes it had been searched
    for.
  . EXAMPLE: ab -scheme new
      always replaces a position in case of a collision.
  . DEFAULT: big1

*/




// ***** start of alibaba.ini *****

#define NUM_KEYS 200


char iniKeys[NUM_KEYS][150] = {
"use_bookthinker","use_resign","pawn_value","knight_value",
"bishop_value","rook_value","queen_value","king_value","Use_New",
"Use_Big1","Use_BigAll","Use_Deep","Use_Old","show_hash_stats",
"castling_incentive","use_draw_offer", "use_hashsize",
"time_adjust","resign_count","resign_score","pawn_value_endgame",
"knight_value_endgame","bishop_value_endgame","rook_value_endgame",
"queen_value_endgame","king_value_endgame","use_insuf_draw"


};

void ReadINIFile(char *filename)
{
FILE *in;
bool foundKey[NUM_KEYS];
char buffer[4000];
char key[120];
int c,i;

use_bookthinker = use_resign = use_draw_offer = use_hashsize =
pawn_value = knight_value = bishop_value = rook_value = queen_value =
king_value = Use_New = Use_Big1 = Use_BigAll = Use_Deep = Use_Old = 
show_hash_stats = castling_incentive = use_draw_offer =
use_hashsize = time_adjust = resign_count = resign_score = pawn_value_endgame =
knight_value_endgame = bishop_value_endgame = rook_value_endgame = queen_value_endgame =
king_value_endgame = 0;


memset(foundKey,false, sizeof(bool)*NUM_KEYS);
memset(buffer,0,sizeof(char) * 4000);

in = fopen(filename, "r");
if(in == NULL) {
printf("\nNo %s file found - setting internal default values.\n\n", filename);
for(i = 0; i < NUM_KEYS; i++) {
}
return;
} else {
printf("\n%s found. Loading values....   \n\n", filename);	
}

for(;;) {
c = fgetc(in);
if(c == '*') {
fscanf(in, "%s %s", key, buffer);
if((i = KeyNum(key)) >= 0) { // test that key is legit
SetINIKey(key, buffer, false);
foundKey[i] = true;
memset(buffer,0,sizeof(char) * 4000);
}
}
if(c == EOF)  {
printf("\ndone. \n\n");	
break;
}
}

//	 Find all keys whose values were no explicitely set in the ini file and set them to the default
for(i = 0; i < NUM_KEYS; i++) {
if(foundKey[i] == false) SetINIKey(iniKeys[i], NULL, true);
}
fclose(in);	
}

int KeyNum(char *key) {
int i;
for(i = 0; i < NUM_KEYS; i++) {
if(!strcmp(key, (char *)iniKeys[i])) return i;
}
return -1;
}

//***** set values from alibaba.ini ******
int SetINIKey(char *key, char *buffer, bool default_val)
{
    
 if (!strcmp(key, "use_bookthinker")) {
		bookthinker_use = atoi(buffer);
        if (bookthinker_use) {
        using_bookthinker = true;                    
        printf("\n[alibaba] using bookthinker selected\n");
        }}
           
				 										         	    									
if (!strcmp(key, "use_resign")) {
		resign_use = atoi(buffer);
        if (resign_use) {
        using_resign = true;                    
        printf("\n[alibaba] using resign selected\n");
        }}
        
        
if (!strcmp(key, "resign_score")) {
		score_resign = atoi(buffer);
        if (score_resign && resign_use) {
        Resign_value = score_resign*10;                    
        printf("\n[alibaba] resign score = -%d",score_resign);
        if (score_resign == 900) printf(" (default)\n");
        else
        printf("\n");
        }}               
        

if (!strcmp(key, "resign_count")) {
		count_resign = atoi(buffer);
        if (count_resign && resign_use) {                    
        printf("\n[alibaba] resign count = %d",count_resign);
        if (count_resign == 3) printf(" (default)\n");
        else
        printf("\n");
        }}        
        
        

        if (!strcmp(key, "time_adjust")) {
		adjust_time = atoi(buffer);
        if (adjust_time) {
        MAX_TIME = adjust_time;                    
        printf("\n[alibaba] time adjust  = %d",adjust_time);
        if (adjust_time == 70) printf(" (default)\n");
        else
        printf("\n");
        }}       
        
        if (!strcmp(key, "pawn_value")) {
		value_pawn = atoi(buffer);
        if (value_pawn) {                    
        printf("\n[alibaba] pawn value   = %d\n",value_pawn);
        }}       
                     
        if (!strcmp(key, "knight_value")) {
		value_knight = atoi(buffer);
        if (value_knight) {                    
        printf("\n[alibaba] knight value = %d\n",value_knight);
        }}        
        
        if (!strcmp(key, "bishop_value")) {
		value_bishop = atoi(buffer);
        if (value_bishop) {                    
        printf("\n[alibaba] bishop value = %d\n",value_bishop);
        }}        
        
        if (!strcmp(key, "rook_value")) {
		value_rook = atoi(buffer);
        if (value_rook) {                    
        printf("\n[alibaba] rook value   = %d\n",value_rook);
        }}        
        
        if (!strcmp(key, "queen_value")) {
		value_queen = atoi(buffer);
        if (value_queen) {                    
        printf("\n[alibaba] queen value  = %d\n",value_queen);
        }}        
        
        if (!strcmp(key, "king_value")) {
		value_king = atoi(buffer);
        if (value_king) {                    
        printf("\n[alibaba] king value   = %d\n",value_king);
        }}      
        
           
        
        if (!strcmp(key, "pawn_value_endgame")) {
		endgame_value_pawn = atoi(buffer);
        if (endgame_value_pawn) {                    
        printf("\n[alibaba] end pawn val   = %d\n",endgame_value_pawn);
        }}       
                     
        if (!strcmp(key, "knight_value_endgame")) {
		endgame_value_knight = atoi(buffer);
        if (endgame_value_knight) {                    
        printf("\n[alibaba] end knight val = %d\n",endgame_value_knight);
        }}        
        
        if (!strcmp(key, "bishop_value_endgame")) {
		endgame_value_bishop = atoi(buffer);
        if (endgame_value_bishop) {                    
        printf("\n[alibaba] end bishop val = %d\n",endgame_value_bishop);
        }}        
        
        if (!strcmp(key, "rook_value_endgame")) {
		endgame_value_rook = atoi(buffer);
        if (endgame_value_rook) {                    
        printf("\n[alibaba] end rook val   = %d\n",endgame_value_rook);
        }}        
        
        if (!strcmp(key, "queen_value_endgame")) {
		endgame_value_queen = atoi(buffer);
        if (endgame_value_queen) {                    
        printf("\n[alibaba] end queen val  = %d\n",endgame_value_queen);
        }}        
        
        if (!strcmp(key, "king_value_endgame")) {
		endgame_value_king = atoi(buffer);
        if (endgame_value_king) {                    
        printf("\n[alibaba] end king val   = %d\n",endgame_value_king);
        }}      
        

        
        
        if (!strcmp(key, "castling_incentive")) {
		incentive_castling = atoi(buffer);
        if (incentive_castling) {                    
        printf("\n[alibaba] castle bonus = %d\n",incentive_castling);
        }}       
                     
               
        if (!strcmp(key, "use_draw_offer")) {
		draw_offer_use = atoi(buffer);
        if (draw_offer_use) {
        using_draw_offer = true;                    
        printf("\n[alibaba] using offer-drw selected\n");
        }} 
        
        if (!strcmp(key, "use_insuf_draw")) {
		insuf_draw_use = atoi(buffer);
        if (insuf_draw_use) {
        using_insufficient_draw = true;                    
        printf("\n[alibaba] using insuf-drw selected\n");
        }}           
        
        
if (!strcmp(key, "use_hashsize")) {
		hashsize_use = atoi(buffer);
        if (hashsize_use) {                  
        printf("\n[alibaba] using hashsize %dmb selected\n", hashsize_use);
        if (hashsize_use == 3)  {
        hashsize = 16; 
        nrTtBits = hashsize;   
        memory_on = false;
        }else
        if (hashsize_use == 6)  {
        hashsize = 17; 
        nrTtBits = hashsize;   
        memory_on = false;
        }else
        if (hashsize_use == 12) { 
        hashsize = 18; 
        nrTtBits = hashsize;   
        memory_on = false;
        }else
        if (hashsize_use == 22) {  
        hashsize = 20; 
        nrTtBits = hashsize;   
        memory_on = false;
        }else
        if (hashsize_use == 32) {  
        hashsize = 19;
        nrTtBits = hashsize;   
        memory_on = false;
        }else
        if (hashsize_use == 82) { 
        hashsize = 22; 
        nrTtBits = hashsize;   
        memory_on = false;
        }else
        if (hashsize_use == 164) {
        hashsize = 23; 
        nrTtBits = hashsize;   
        memory_on = false;
        }else{
        printf("[alibaba] hash size selected not supported\n");
        printf("[alibaba] using default 32mb hash size\n");
        }
        }}  
        
          
        
        if (!strcmp(key, "Use_New")) {
		new_use = atoi(buffer);
        if (new_use) {                    
        printf("\n[alibaba] hashtable keep method = new\n");
        }}        

        if (!strcmp(key, "Use_Big1")) {
		big1_use = atoi(buffer);
        if (big1_use) {                    
        printf("\n[alibaba] hashtable keep method = big1\n");
        }}        

        if (!strcmp(key, "Use_BigAll")) {
		bigall_use = atoi(buffer);
        if (bigall_use) {                    
        printf("\n[alibaba] hashtable keep method = bigall\n");
        }}        

        if (!strcmp(key, "Use_Deep")) {
		deep_use = atoi(buffer);
        if (deep_use) {                    
        printf("\n[alibaba] hashtable keep method = deep\n");
        }}        

        if (!strcmp(key, "Use_Old")) {
		old_use = atoi(buffer);
        if (old_use) {                    
        printf("\n[alibaba] hashtable keep method = old\n");
        }}        

        if (!strcmp(key, "show_hash_stats")) {
		hash_stats_show = atoi(buffer);
        if (hash_stats_show) {                    
        printf("\n[alibaba] show hash stats       = yes\n");
        }}        

       

return 0;
}

//***** end of alibaba.ini  ****************




/*----------------------------------------------------------------------
 | INIT							940420
 |
 | Contains procedures concerning the initialization of several
 | variables.
 +----------------------------------------------------------------------*/



static void     InitMoveTables(void);
static void     InitKnightTable(void);
static void     InitBishopTable(void);
static void     InitRookTable(void);
static void     InitPawnMoveTables(void);
static void     InitPawnCaptureTables(void);
static void     InitPieceSymbols(void);
static void     InitPieceValues(void);
static void     InitAllocVariables(void);
static void     FillHashTables(void);
static void     InitPackArrays(void);
static void     UpdatePieceTables(void);
static Boolean  Unique(HashType h);
static void     CheckHashTables(void);



static int             get_ms(void)
{
    struct timeb    timebuffer;
    ftime(&timebuffer);
    if (timebuffer.millitm != 0)
        ftime_ok = true;
    return (timebuffer.time * 1000) + timebuffer.millitm;
    }


/* ab.c */
extern void     Search(Signed1 depth, MoveType * move, ValueType * value);
extern void     FreePath(PathType * path);

/* command.c */
extern Signed2  InterpretCommand(void);
extern void     PerformMoveCommand(char *moveString);
extern void     PerformPlacePiece(char *pieceString);


/* evaluate.c */
extern ValueType Evaluate(Signed1 ttDepth, ValueType ttValue, Unsigned1 flag,
                                          Unsigned4 ttNodes);

/* generate.c */
extern void     GenerateMoves(MoveType ** moveList, Unsigned1 * nrMoves);
extern Boolean  Attacked(BoardIndexType square, SquareType color);

#ifdef WINDOWS
extern Boolean  FindFirstPieceInDir(Unsigned1 max,
                   BoardIndexType huge * table, PieceType * attackingPiece);
#else
extern Boolean  FindFirstPieceInDir(Unsigned1 max, BoardIndexType * table,
                                                PieceType * attackingPiece);
#endif

extern void     SearchForPinsAndCheck(void);
extern void     GenerateCaptureMoves(CheckPieceType * piece, MoveType * list,
                                                     Unsigned1 * nrMoves);
extern void     GenerateInterposingMoves(CheckPieceType * piece, MoveType * list,
                                                       Unsigned1 * nrMoves);
extern void     GenerateKingMoves(BoardIndexType square, MoveType * list,
                                                  Unsigned1 * nrMoves);
extern Signed2  CompareMoves(MoveType * move1, MoveType * move2);
extern void     HeapSort(MoveType * moveList, Unsigned1 nrMoves);
extern void     SiftDown(MoveType * moveList, Unsigned1 root, Unsigned1 leaf);

/* init.c */
extern void     Init(void);
extern void     EmptyBoard(void);
extern void     PieceCount(void);
extern void     StartingPosition(void);
extern void     PlacePiece(SquareType piece, BoardIndexType square);
extern void     ClearHistoryTables(void);
extern void     ClearPieceSquareTables(void);
extern void     InitPositionalValue(void);
extern void     InitTransTable(void);

/* io.c */
extern void     PrintBoard(void);
extern void     PrintMoveList(MoveType * list, Unsigned1 nrMoves);
extern void     PrintAllocVariables(void);
extern void     PrintGame(Signed2 from, Signed2 to);
extern void     PrintPath(PathType * path);
extern void     PrintHistoryTable(void);
extern void     PrintHashes(void);
extern void     PrintSettings(void);
extern void     PrintTestSettings(Signed2 testDepth, Signed2 testColor,
                                                  Signed4 testNrNodes);

/* move.c */
extern void     DoMove(MoveType * move);
extern void     UndoMove(void);

/* quies.c */
extern ValueType Quiescence(ValueType alpha, ValueType beta,
                   PathType ** bestPath, Signed1 ttDepth, ValueType ttValue,
                                         Unsigned1 flag, Unsigned4 ttNodes);

/* search.c */
extern void     PreProcessing(void);
extern Signed2  ItIsADraw(void);

/* testing.c */
extern void     TestArguments(void);


extern BoardIndexType lastMovedPieceSquare;
extern Unsigned1 nrCheck;
extern CheckPieceType checkingPiece[2];
extern DirectionType pinned[H8 + 1];
extern SquareType board[NrSquares];
extern BoardIndexType epSquare[MaxGamePlies];
extern Unsigned1 castling[MaxGamePlies];
extern HashType hashValue[MaxGamePlies];
extern Unsigned2 startHashIndex[MaxGamePlies];
extern SquareType toMove;
extern Unsigned4 material[2];
extern ValueType positionalValue[2];
extern Unsigned2 pieceValue[128];
extern char     pieceSymbol[256];
extern PieceType pieces[2][16];
extern Unsigned1 nrPieces[2];
extern Unsigned1 pieceIndex[H8 + 1];
extern BoardIndexType kingSquare[2];
extern char     gameString[MaxGamePlies][MaxMoveLength];
extern MoveType game[MaxGamePlies];
extern Unsigned2 nrGamePlies,
                maxGamePlies;
extern Unsigned2 startPly;
extern SquareType computer;
extern Unsigned4 nrInternalNodes,
                nrLeafNodes,
                nrQuiesNodes;
extern Unsigned4 nrIllegalMoves;
extern Unsigned4 nrTotalNodes,
                nrExtraNodes;
extern double   startingTime;
extern Unsigned2 nrAllocMoveLists,
                nrAllocPathMoves;
extern Boolean  stopSearching;
extern char    *moveColorString[2];

#ifdef WINDOWS
extern huge Unsigned2 historyTable[2][H8 + 1][H8 + 1];
#else
extern Unsigned2 historyTable[2][H8 + 1][H8 + 1];
#endif

extern Signed2  pawnEvalTable[2][H8 + 1];
extern Signed2  knightEvalTable[2][H8 + 1];
extern Signed2  bishopEvalTable[2][H8 + 1];
extern Signed2  rookEvalTable[2][H8 + 1];
extern Signed2  queenEvalTable[2][H8 + 1];
extern Signed2  kingEvalTable[2][H8 + 1];
extern Signed2  centreTable[H8 + 1];
extern Boolean  doTest,
                useTransTable,
                useRefTable;
extern Boolean  useTwoLevelTable,
                useTtValue,
                useTtMove,
                timeStamp;
extern Boolean  useFlag;
extern char    *version;
extern TtEntry *transTable;
extern Unsigned4 nrCollisions,
                nrHits,
                nrReads,
                nrWrites;
extern Signed4  testNrNodes;
//extern Unsigned1 nrTtBits;
extern Unsigned2 keepPly;
extern Unsigned1 keepMethod;
extern char    *methodString[5];
extern Unsigned2 debugDepth;

extern char    *logicString[2];

extern Unsigned1 packPiece[Edge];
extern SquareType unpackPiece[4];       /* 2 bits */
extern Unsigned1 packSquare[H8 + 1];
extern BoardIndexType unpackSquare[64]; /* 6 bits */
extern Unsigned1 packType[64];
extern Unsigned1 unpackType[8]; /* 3 bits */

#ifdef MSC_VER
extern huge BoardIndexType knightTable[H8 + 1][MaxKnightMoves];
extern huge BoardIndexType bishopTable[H8 + 1][4][MaxBishopMoves];
extern huge BoardIndexType rookTable[H8 + 1][4][MaxRookMoves];
extern huge BoardIndexType pawnMoveTable[2][H8 + 1][2];
extern huge BoardIndexType pawnCaptureTable[2][H8 + 1][2];
#else
extern BoardIndexType knightTable[H8 + 1][MaxKnightMoves];
extern BoardIndexType bishopTable[H8 + 1][4][MaxBishopMoves];
extern BoardIndexType rookTable[H8 + 1][4][MaxRookMoves];
extern BoardIndexType pawnMoveTable[2][H8 + 1][2];
extern BoardIndexType pawnCaptureTable[2][H8 + 1][2];
#endif

extern DirectionType knightDir[8],
                bishopDir[4],
                rookDir[4];
extern DirectionType pawnCaptureDir[2][2];

extern char    *commandString[MaxCommands][2];

extern HashType pawnHashTable[2][H8 + 1];
extern HashType knightHashTable[2][H8 + 1];
extern HashType bishopHashTable[2][H8 + 1];
extern HashType rookHashTable[2][H8 + 1];
extern HashType queenHashTable[2][H8 + 1];
extern HashType kingHashTable[2][H8 + 1];
extern HashType movedHash;
extern HashType enPassantHashTable[H + 1];
extern HashType castlingHashTable[2][2];

extern Boolean  printDebug;
extern Unsigned4 nrMovesGenerated,
                nrGenerates;
                


BoardIndexType  lastMovedPieceSquare;   /* Square last played piece moved to */
Unsigned1       nrCheck;
CheckPieceType  checkingPiece[2];
DirectionType   pinned[H8 + 1];
SquareType      board[NrSquares];
BoardIndexType  epSquare[MaxGamePlies]; /* EP status during game */
Unsigned1       castling[MaxGamePlies]; /* castling status during game */
HashType        hashValue[MaxGamePlies];        /* hash values of game
                                                 * positions */
Unsigned2       startHashIndex[MaxGamePlies];   /* 50 move rule indices */
SquareType      toMove;
Unsigned4       material[2];
ValueType       positionalValue[2];
Unsigned2       pieceValue[128];
char            pieceSymbol[256];
PieceType       pieces[2][16];
Unsigned1       nrPieces[2];
Unsigned1       pieceIndex[H8 + 1];
BoardIndexType  kingSquare[2];
char            gameString[MaxGamePlies][MaxMoveLength];        /* moveStrings */
MoveType        game[MaxGamePlies];     /* Real moves in the game */
Unsigned2       nrGamePlies,
                maxGamePlies;
Unsigned2       startPly;       /* Ply number of game when the search starts */
SquareType      computer;
Unsigned4       nrInternalNodes,
                nrLeafNodes,
                nrQuiesNodes;
Unsigned4       nrIllegalMoves;
double          startingTime;
Unsigned4       nrTotalNodes,
                nrExtraNodes;
Unsigned2       nrAllocMoveLists,
                nrAllocPathMoves;
Boolean         stopSearching;
char           *moveColorString[2] =
{"BTM", "WTM"};

#ifdef WINDOWS
Unsigned2 huge  historyTable[2][H8 + 1][H8 + 1];
#else
Unsigned2       historyTable[2][H8 + 1][H8 + 1];
#endif

Signed2         pawnEvalTable[2][H8 + 1];
Signed2         knightEvalTable[2][H8 + 1];
Signed2         bishopEvalTable[2][H8 + 1];
Signed2         rookEvalTable[2][H8 + 1];
Signed2         queenEvalTable[2][H8 + 1];
Signed2         kingEvalTable[2][H8 + 1];

Boolean         interActive,
                doTest,
                useTransTable,
                useRefTable;
Boolean         useTwoLevelTable,
                useTtValue,
                useTtMove,
                timeStamp,
                useFlag;
TtEntry        *transTable;
Unsigned4       nrCollisions,
                nrHits,
                nrReads,
                nrWrites;
Signed4         testNrNodes;
Unsigned1       nrTtBits;
Unsigned2       keepPly;
Unsigned1       keepMethod;
char           *methodString[5] =
{"New", "Old", "Deep", "Big1", "BigAll"};
Unsigned2       debugDepth;

char           *logicString[2] =
{"false", "true"};

/* pack arrays because of transposition table entries */
Unsigned1       packPiece[Edge];
SquareType      unpackPiece[4]; /* 2 bits */
Unsigned1       packSquare[H8 + 1];
BoardIndexType  unpackSquare[64];       /* 6 bits */
Unsigned1       packType[64];
Unsigned1       unpackType[8];  /* 3 bits */

/* move tables */
#ifdef WINDOWS
BoardIndexType huge knightTable[H8 + 1][MaxKnightMoves];
BoardIndexType huge bishopTable[H8 + 1][4][MaxBishopMoves];
BoardIndexType huge rookTable[H8 + 1][4][MaxRookMoves];
BoardIndexType huge pawnMoveTable[2][H8 + 1][2];
BoardIndexType huge pawnCaptureTable[2][H8 + 1][2];
#else
BoardIndexType  knightTable[H8 + 1][MaxKnightMoves];
BoardIndexType  bishopTable[H8 + 1][4][MaxBishopMoves];
BoardIndexType  rookTable[H8 + 1][4][MaxRookMoves];
BoardIndexType  pawnMoveTable[2][H8 + 1][2];
BoardIndexType  pawnCaptureTable[2][H8 + 1][2];
#endif

/* move directions */
DirectionType   knightDir[8] =
{Up + Up + Right, Up + Up + Left, Down + Down + Right,
    Down + Down + Left, Right + Right + Up, Right + Right + Down,
Left + Left + Up, Left + Left + Down};
DirectionType   bishopDir[4] =
{Up + Right, Up + Left, Down + Right, Down + Left};
DirectionType   rookDir[4] =
{Up, Down, Right, Left};
DirectionType   pawnCaptureDir[2][2] =
{
    {Down + Right, Down + Left},
{Up + Right, Up + Left}};



 Signed2         KingTable[H8 + 1] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 10, 20, 40, 40, 20, 10, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 10, 30, 50, 70, 70, 50, 30, 10, 0, 0, 0, 0, 0, 0, 0,
    0, 20, 50, 80, 110, 110, 80, 50, 20, 0, 0, 0, 0, 0, 0, 0,
    0, 40, 70, 110, 160, 160, 110, 70, 40, 0, 0, 0, 0, 0, 0, 0,
    0, 40, 70, 110, 160, 160, 110, 70, 40, 0, 0, 0, 0, 0, 0, 0,
    0, 20, 50, 80, 110, 110, 80, 50, 20, 0, 0, 0, 0, 0, 0, 0,
    0, 10, 30, 50, 70, 70, 50, 30, 10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 10, 20, 40, 40, 20, 10, 0};
 

 

Signed2         PawnTable[H8 + 1] =
{   0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0,
    0, 16, 16, 16,  6,  6, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0, 16, 12,-10,-10,-10, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0, 16, 12, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  1,  5,  8,  8,  5,  1,  0, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  1,  6, 16, 12,  6,  1,  0, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0, 16, 12, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0, 16, 12,-10,-10,-10, 0, 0, 0, 0, 0, 0, 0, 
    0, 16, 16, 16,  6,  6, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0,  0,  0,  0,  0,  0
};




Signed2         KnightTable[H8 + 1] =
{
-16,-16,-16,-16,-16,-16,-16,-16,-16,                0, 0, 0, 0, 0, 0, 0,
-8,-16,-10, -8, -8, -8, -8,-10,-16,  0, 0, 0, 0, 0, 0, 0, 
-8,-10, -3,  1,  3,  3,  1, -3,-10,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  1,  5,  5,  5,  5,  1, -8,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  2,  16, 16, 16,  5,  2, -8,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  4,  16, 16, 16,  6,  4, -8,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  4,  16, 16, 16,  7,  4, -8,  0, 0, 0, 0, 0, 0, 0, 
-8,-10,  0,  3,  4,  4,  3,  0,-10,  0, 0, 0, 0, 0, 0, 0, 
-8,-16,-10, -8, -8, -8, -8,-10,-16,  0, 0, 0, 0, 0, 0, 0, 
-16, -16,-16, -16,-16,-16,-16,-16,-16
}; 




Signed2         RookTable[H8 + 1] =
{   0,  0,  0,   0,   0,   0,   0,   0,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  0,   0,   0,   0,   0,   0,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  8,  8,   8,   8,   8,   8,   8,  8,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  1,   2,   3,   3,   2,   1,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  1,   2,   3,   3,   2,   1,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  1,   2,   3,   3,   2,   1,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  7,  8,   9,  10,  10,   9,   8,  7,  0, 0, 0, 0, 0, 0, 0, 
    0, 10, 11,  12,  13,  13,  12,  11,  10, 0, 0, 0, 0, 0, 0, 0,
    0, 10, 11,  12,  13,  13,  12,  11,  10, 0, 0, 0, 0, 0, 0, 0,
    0,  0,  0,   0,   0,   0,   0,   0 
};


Signed2         BishopTable[H8 + 1] =
{
    0,  0,  0,   0,   0,   0,   0,   0,  0,  0, 0, 0, 0, 0, 0, 0,
	0, 10,  8,   6,   4,   4,   6,   8,  10, 0, 0, 0, 0, 0, 0, 0, 
    0,  8, 12,   8,   9,   9,   8,  12,   8, 0, 0, 0, 0, 0, 0, 0, 
    0, 10, 10,  11,  11,  11,  11,  10,  10, 0, 0, 0, 0, 0, 0, 0,
    0, 11, 12,  13,  14,  14,  13,  12,  11, 0, 0, 0, 0, 0, 0, 0,
    0, 12, 13,  15,  17,  17,  15,  14,  12, 0, 0, 0, 0, 0, 0, 0,
    0, 13, 14,  16,  16,  16,  16,  14,  13, 0, 0, 0, 0, 0, 0, 0,
    0, 11, 14,  12,  12,  12,  12,  14,  11, 0, 0, 0, 0, 0, 0, 0,
    0, 13, 10,  10,  10,  10,  10,  10,  13, 0, 0, 0, 0, 0, 0, 0,
    0,  0,  -16,   0,   0,   -16,   0,   0 
};



Signed2         QueenTable[H8 + 1] =
{
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 
  0,  0,  1,  2,  3,  3,  2,  1,  0,  0, 0, 0, 0, 0, 0, 
  0,  8,  8,  8,  8,  8,  8,  8,  8,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  7,  8,  8,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  6,  7,  8,  9,  9,  8,  7,  6,  0, 0, 0, 0, 0, 0, 0, 
  0,  6,  7,  16,  16,  16,  8,  7,  6,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  16,  16,  16,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  7,  8,  8,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  7,  8,  8,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  0,  0,   -16,   0,   0,   0,  0,  0  
};







Signed2         KingTable_Endgame[H8 + 1] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 10, 20, 40, 40, 20, 10, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 10, 30, 50, 70, 70, 50, 30, 10, 0, 0, 0, 0, 0, 0, 0,
    0, 20, 50, 80, 110, 110, 80, 50, 20, 0, 0, 0, 0, 0, 0, 0,
    0, 40, 70, 110, 160, 160, 110, 70, 40, 0, 0, 0, 0, 0, 0, 0,
    0, 40, 70, 110, 160, 160, 110, 70, 40, 0, 0, 0, 0, 0, 0, 0,
    0, 20, 50, 80, 110, 110, 80, 50, 20, 0, 0, 0, 0, 0, 0, 0,
    0, 10, 30, 50, 70, 70, 50, 30, 10, 0, 0, 0, 0, 0, 0, 0,
0, 0, 10, 20, 40, 40, 20, 10, 0};
 

 

Signed2         PawnTable_Endgame[H8 + 1] =
{   0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0,
    0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0,
    0,  8,  8,  8,  8,  8,  8,  8,  8, 0, 0, 0, 0, 0, 0, 0, 
    0,  2,  3,  4,  6,  6,  4,  3,  2, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  1,  5,  8,  8,  5,  1,  0, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  1,  6, 16, 12,  6,  1,  0, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0, 16, 12, -5, -5, -5, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0, 16, 12,-10,-10,-10, 0, 0, 0, 0, 0, 0, 0, 
    0, 16, 16, 16,  6,  6, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 
    0,  0,  0,  0,  0,  0,  0,  0,  0
};




Signed2         KnightTable_Endgame[H8 + 1] =
{
-16,-16,-16,-16,-16,-16,-16,-16,-16,                0, 0, 0, 0, 0, 0, 0,
-8,-16,-10, -8, -8, -8, -8,-10,-16,  0, 0, 0, 0, 0, 0, 0, 
-8,-10, -3,  1,  3,  3,  1, -3,-10,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  1,  5,  5,  5,  5,  1, -8,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  2,  16, 16, 16,  5,  2, -8,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  4,  16, 16, 16,  6,  4, -8,  0, 0, 0, 0, 0, 0, 0, 
-8, -8,  4,  16, 16, 16,  7,  4, -8,  0, 0, 0, 0, 0, 0, 0, 
-8,-10,  0,  3,  4,  4,  3,  0,-10,  0, 0, 0, 0, 0, 0, 0, 
-8,-16,-10, -8, -8, -8, -8,-10,-16,  0, 0, 0, 0, 0, 0, 0, 
-16, -16,-16, -16,-16,-16,-16,-16,-16
}; 




Signed2         RookTable_Endgame[H8 + 1] =
{   0,  0,  0,   0,   0,   0,   0,   0,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  0,   0,   0,   0,   0,   0,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  8,  8,   8,   8,   8,   8,   8,  8,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  1,   2,   3,   3,   2,   1,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  1,   2,   3,   3,   2,   1,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  0,  1,   2,   3,   3,   2,   1,  0,  0, 0, 0, 0, 0, 0, 0,
    0,  7,  8,   9,  10,  10,   9,   8,  7,  0, 0, 0, 0, 0, 0, 0, 
    0, 10, 11,  12,  13,  13,  12,  11,  10, 0, 0, 0, 0, 0, 0, 0,
    0, 10, 11,  12,  13,  13,  12,  11,  10, 0, 0, 0, 0, 0, 0, 0,
    0,  0,  0,   0,   0,   0,   0,   0 
};


Signed2         BishopTable_Endgame[H8 + 1] =
{
    0,  0,  0,   0,   0,   0,   0,   0,  0,  0, 0, 0, 0, 0, 0, 0,
	0, 10,  8,   6,   4,   4,   6,   8,  10, 0, 0, 0, 0, 0, 0, 0, 
    0,  8, 12,   8,   9,   9,   8,  12,   8, 0, 0, 0, 0, 0, 0, 0, 
    0, 10, 10,  11,  11,  11,  11,  10,  10, 0, 0, 0, 0, 0, 0, 0,
    0, 11, 12,  13,  14,  14,  13,  12,  11, 0, 0, 0, 0, 0, 0, 0,
    0, 12, 13,  15,  17,  17,  15,  14,  12, 0, 0, 0, 0, 0, 0, 0,
    0, 13, 14,  16,  16,  16,  16,  14,  13, 0, 0, 0, 0, 0, 0, 0,
    0, 11, 14,  12,  12,  12,  12,  14,  11, 0, 0, 0, 0, 0, 0, 0,
    0, 13, 10,  10,  10,  10,  10,  10,  13, 0, 0, 0, 0, 0, 0, 0,
    0,  0,  -16,   0,   0,   -16,   0,   0 
};



Signed2         QueenTable_Endgame[H8 + 1] =
{
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 
  0,  0,  1,  2,  3,  3,  2,  1,  0,  0, 0, 0, 0, 0, 0, 
  0,  8,  8,  8,  8,  8,  8,  8,  8,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  7,  8,  8,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  6,  7,  8,  9,  9,  8,  7,  6,  0, 0, 0, 0, 0, 0, 0, 
  0,  6,  7,  16,  16,  16,  8,  7,  6,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  16,  16,  16,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  7,  8,  8,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  5,  6,  7,  8,  8,  7,  6,  5,  0, 0, 0, 0, 0, 0, 0, 
  0,  0,  0,   -16,   0,   0,   0,  0,  0  
};








HashType        pawnHashTable[2][H8 + 1];
HashType        knightHashTable[2][H8 + 1];
HashType        bishopHashTable[2][H8 + 1];
HashType        rookHashTable[2][H8 + 1];
HashType        queenHashTable[2][H8 + 1];
HashType        kingHashTable[2][H8 + 1];
HashType        movedHash;
HashType        enPassantHashTable[H + 1];
HashType        castlingHashTable[2][2];

Boolean         printDebug;

char           *version = "24 january 1995";

Unsigned4       nrMovesGenerated,
                nrGenerates;


static void     SetTestingDefaults(Signed2 * testDepth, Signed2 * testColor,
                                                   Signed4 testNrNodes);
static void     SetDefaults(Boolean * useTransTable, Boolean * useRefTable,
                           Unsigned1 * nrTtBits, Boolean * useTwoLevelTable,
                                            Boolean * useTtValue, Boolean * useTtMove, Boolean * timeStamp,
                                            Boolean * useFlag);
static void     PerformTest(Signed2 startingMove, Signed2 testColor,
                                            Signed2 testDepth);


void            TestArguments()
{
    Signed2         i;
    Signed2         testDepth,
                    testColor,
                    startingMove;
    MoveType        move;
    ValueType       value;
    char            s[MaxMoveLength];

    doTest = false;
    testDepth = testColor = -1;
    testNrNodes = -1;
    debugDepth = 0;

	useTransTable    = TransTableDefault;
	useRefTable      = RefTableDefault;
	useTwoLevelTable = TwoLevelTableDefault;
	useTtValue       = TtValueDefault;
	useTtMove        = TtMoveDefault;
    useFlag          = UseFlagDefault;
    timeStamp        = TimeStampDefault;
    if (!hashsize) nrTtBits   = TtBitsDefault;
	else
    nrTtBits = hashsize; 
	
	keepPly          = KeepPlyDefault;
  
    if (new_use)      keepMethod = New;
	else
	if (big1_use)     keepMethod = Big1;
	else
	if (bigall_use)   keepMethod = BigAll;
	else
	if (deep_use)     keepMethod = Deep;
	else
	if (old_use)      keepMethod = Old;

   

    SetDefaults(&useTransTable, &useRefTable, &nrTtBits, &useTwoLevelTable,
                &useTtValue, &useTtMove, &timeStamp, &useFlag);
    PrintSettings();
    if (useTransTable) {
        printf("Initializing transposition table (%lu entries * %d)",
               1L << nrTtBits, sizeof(TtEntry));
        printf(" --> %lu bytes", (1L << nrTtBits) * sizeof(TtEntry));
        fflush(stdout);
        InitTransTable();
        printf("\n");
        if (useTwoLevelTable) { /* 2 positions per entry: hash,
                                 * hash+1<<nrTtBits */
            nrTtBits--;
        }
        if (nrTtBits < (sizeof(TtEntry) <= 16 ? 15 : 7)) {
            printf("\nERROR: nrTtBits must be at least %d.\n",
                   (sizeof(TtEntry) <= 16 ? 15 : 7));
            exit(0);
        }
    }
   
      
    
}                                  
                
                
/* Copyright (c) 1993 Martin Birgmeier
 * All rights reserved.
 *
 * You may redistribute unmodified or modified versions of this source
 * code provided that the above copyright notice and this and the
 * following conditions are retained.
 *
 * This software is provided ``as is'', and comes with no warranties
 * of any kind. I shall in no event be liable for anything that happens
 * to anyone/anything when using this software.
 */

#ifndef _RAND48_H_
#define _RAND48_H_

#include <math.h>
#include <stdlib.h>
extern double drand48(void );
extern double erand48(unsigned short *xseed);
extern void _dorand48(unsigned short *xseed);
extern void srand48(long seed);

#define	RAND48_SEED_0	(0x330e)
#define	RAND48_SEED_1	(0xabcd)
#define	RAND48_SEED_2	(0x1234)
#define	RAND48_MULT_0	(0xe66d)
#define	RAND48_MULT_1	(0xdeec)
#define	RAND48_MULT_2	(0x0005)
#define	RAND48_ADD	(0x000b)

#endif /* _RAND48_H_ */
          
                
                
                
