From fd1460b2c135f6cef502fd167d1df0edf223e312 Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Sun, 30 Aug 2026 17:17:44 -0700 Subject: Improving for nullmove, eval speedup, remove old cruft, bugfix in split / MP. --- src/chess.h | 1 + src/chess.hbak | 2988 ------------------------------------------------------- src/eval.c | 79 +- src/root.c | 2 +- src/search.c | 14 +- src/searchsup.c | 24 +- 6 files changed, 49 insertions(+), 3059 deletions(-) delete mode 100755 src/chess.hbak (limited to 'src') diff --git a/src/chess.h b/src/chess.h index a83a13d..367100f 100755 --- a/src/chess.h +++ b/src/chess.h @@ -2413,6 +2413,7 @@ WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, IN SCORE iAlpha, IN SCORE iBeta, IN SCORE iRoughEval, + IN SCORE iImprovement, IN ULONG uNullDepth); FLAG diff --git a/src/chess.hbak b/src/chess.hbak deleted file mode 100755 index e64569a..0000000 --- a/src/chess.hbak +++ /dev/null @@ -1,2988 +0,0 @@ -/** - -Copyright (c) Scott Gasch - -Module Name: - - chess.h - -Abstract: - -Author: - - Scott Gasch (scott@wannabe.guru.org) 7 Apr 2004 - -Revision History: - - $Id: chess.h 344 2007-11-30 06:49:50Z scott $ - -**/ - -#ifndef CHESS_ -#define CHESS_ - -#include "compiler.h" - -// -// Datatype wrappers -// -#define MIN_CHAR (0x80) -#define MAX_CHAR (0x7f) -typedef char CHAR; - -#define MIN_BYTE (0x00) -#define MAX_BYTE (0xff) -typedef unsigned char BYTE; - -#define MIN_UCHAR (0x00) -#define MAX_UCHAR (0xff) -typedef unsigned char UCHAR; -#define CAN_FIT_IN_UCHAR(x) ((x) <= MAX_UCHAR) - -#define MIN_SHORT (0x8000) -#define MAX_SHORT (0x7fff) -typedef signed short SHORT; - -#define MIN_USHORT (0x0000) -#define MAX_USHORT (0xffff) -typedef unsigned short USHORT; -#define CAN_FIT_IN_USHORT(x) ((x) <= MAX_USHORT) - -#define MIN_WORD (0x0000) -#define MAX_WORD (0xffff) -typedef unsigned short WORD; - -#define MIN_INT (0x80000000) -#define MAX_INT (0x7fffffff) -typedef signed int INT; - -#define MIN_DWORD (0x00000000) -#define MAX_DWORD (0xffffffff) -typedef unsigned int DWORD; - -#define MIN_UINT (0x00000000) -#define MAX_UINT (0xffffffff) -typedef unsigned int UINT; - -#define MIN_ULONG (0x00000000) -#define MAX_ULONG (0xffffffff) -typedef unsigned int ULONG; - -#define MIN_INT64 (0x8000000000000000) -#define MAX_INT64 (0x7fffffffffffffff) -typedef signed COMPILER_LONGLONG INT64; - -#define MIN_UINT64 (0x0000000000000000) -#define MAX_UINT64 (0xffffffffffffffff) -typedef unsigned COMPILER_LONGLONG UINT64; - -#define MIN_BITBOARD (0x0000000000000000) -#define MAX_BITBOARD (0xffffffffffffffff) -typedef UINT64 BITBOARD; - -#define MIN_BITV MIN_UINT -#define MAX_BITV MAX_UINT -typedef unsigned int BITV; - -#define MIN_FLAG MIN_UINT -#define MAX_FLAG MAX_UINT -typedef unsigned int FLAG; -#define IS_VALID_FLAG(x) (((x) == TRUE) || ((x) == FALSE)) - -typedef unsigned int COOR; -typedef unsigned int PIECE; -typedef signed int SCORE; - -#define BIT1 (0x1) -#define BIT2 (0x2) -#define BIT3 (0x4) -#define BIT4 (0x8) -#define BIT5 (0x10) -#define BIT6 (0x20) -#define BIT7 (0x40) -#define BIT8 (0x80) -#define BIT9 (0x100) -#define BIT10 (0x200) -#define BIT11 (0x400) -#define BIT12 (0x800) -#define BIT13 (0x1000) -#define BIT14 (0x2000) -#define BIT15 (0x4000) -#define BIT16 (0x8000) -#define BIT17 (0x10000) -#define BIT18 (0x20000) -#define BIT19 (0x40000) -#define BIT20 (0x80000) -#define BIT21 (0x100000) -#define BIT22 (0x200000) -#define BIT23 (0x400000) -#define BIT24 (0x800000) -#define BIT25 (0x1000000) -#define BIT26 (0x2000000) -#define BIT27 (0x4000000) -#define BIT28 (0x8000000) -#define BIT29 (0x10000000) -#define BIT30 (0x20000000) -#define BIT31 (0x40000000) -#define BIT32 (0x80000000) - -typedef struct _DLIST_ENTRY -{ - struct _DLIST_ENTRY *pFlink; - struct _DLIST_ENTRY *pBlink; -} DLIST_ENTRY; - -// -// Constants -// -#define YES (1) -#define NO (0) -#ifndef TRUE -#define TRUE (YES) -#endif -#ifndef FALSE -#define FALSE (NO) -#endif - -// -// Calculate the length of an array (i.e. number of elements) -// -#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) -#define COMMAND(x) \ - void (x)(CHAR *szInput, ULONG argc, CHAR *argv[], POSITION *pos) -#define MB (1024 * 1024) - -// -// Calculate the address of the base of the structure given its type, and an -// address of a field within the structure. -// -#ifndef OFFSET_OF -#define OFFSET_OF(field, type) \ - (ULONG)(&((type *)0)->field) -#endif -#ifndef CONTAINING_STRUCT -#define CONTAINING_STRUCT(address, type, field) \ - ((type *)((BYTE *)(address) - (BYTE *)(OFFSET_OF(field, type)))) -#endif - -#define WHITE (1) -#define BLACK (0) -#define BAD_COLOR (2) -#define IS_VALID_COLOR(x) (((x) == WHITE) || ((x) == BLACK)) -#define FOREACH_COLOR(x) for((x) = BLACK; (x) < BAD_COLOR; (x)++) -#define RANDOM_COLOR (rand() & 1) -#define FLIP(color) ((color) ^ 1) -#define COLOR_NAME(color) (((color) == WHITE) ? "white" : "black") - -#define MAX_MOVES_PER_PLY (218) -#define MAX_PLY_PER_SEARCH (64) -#define MAX_MOVES_PER_GAME (1024) -#define SMALL_STRING_LEN_CHAR (256) -#define MEDIUM_STRING_LEN_CHAR (8192) -#define BIG_STRING_LEN_CHAR (16384) - -#define QUARTER_PLY 16 -#define HALF_PLY 32 -#define THREE_QUARTERS_PLY 48 -#define ONE_PLY 64 -#define TWO_PLY 128 -#define THREE_PLY 192 -#define FOUR_PLY 256 -#define MAX_DEPTH_PER_SEARCH (MAX_PLY_PER_SEARCH * ONE_PLY) - -#define IS_VALID_DEPTH(x) (((x) >= 0) && \ - ((x) <= MAX_DEPTH_PER_SEARCH) && \ - (((x) & 0xfffff00f) == 0)) - -#define INFINITY (MAX_SHORT) -#define INVALID_SCORE (INFINITY + 1) -#define IS_VALID_SCORE(x) (((x) >= -INFINITY) && \ - ((x) <= +INFINITY)) -#define NMATE (+INFINITY - 200) -#define MATED_SCORE(ply) (-INFINITY + (ply)) - -#define IS_A_POWER_OF_2(x) (((x) & (x - 1)) == 0) -// -// Program version number -// -#define VERSION "1.00" -#define REVISION "$Id: chess.h 344 2007-11-30 06:49:50Z scott $\n" - -// -// Function decorators -// -#define IN -#define OUT -#define INOUT -#define UNUSED -#define NOTHING - -// ---------------------------------------------------------------------- -// -// PIECE: -// -// a piece (4 bits) = type (3 bits) + color (1 bit) -// -// 3 1 0 -// . . . . -// | | | -// type C -// -#define KING (6) // 110X -#define QUEEN (5) // 101X -#define ROOK (4) // 100X -#define BISHOP (3) // 011X -#define KNIGHT (2) // 010X -#define PAWN (1) // 001X -#define EMPTY (0) // 000X - -// (WHATEVER << 1) -#define BLACK_PAWN (2) // 0010 -#define BLACK_KNIGHT (4) // 0100 -#define BLACK_BISHOP (6) // 0110 -#define BLACK_ROOK (8) // 1000 -#define BLACK_QUEEN (10) // 1010 -#define BLACK_KING (12) // 1100 - -// (WHATEVER << 1) | WHITE -#define WHITE_PAWN (3) // 0011 -#define WHITE_KNIGHT (5) // 0101 -#define WHITE_BISHOP (7) // 0111 -#define WHITE_ROOK (9) // 1001 -#define WHITE_QUEEN (11) // 1011 -#define WHITE_KING (13) // 1101 - -#define PIECE_TYPE(p) ((p) >> 1) -#define PIECE_COLOR(p) ((p) & WHITE) -#define RANDOM_PIECE (rand() % 12) + 2; -#define IS_PAWN(p) (((p) & 0xE) == BLACK_PAWN) -#define IS_KNIGHT(p) (((p) & 0xE) == BLACK_KNIGHT) -#define IS_BISHOP(p) (((p) & 0xE) == BLACK_BISHOP) -#define IS_ROOK(p) (((p) & 0xE) == BLACK_ROOK) -#define IS_QUEEN(p) (((p) & 0xE) == BLACK_QUEEN) -#define IS_KING(p) (((p) & 0xE) == BLACK_KING) -#define IS_KNIGHT_OR_KING(p) (((p) & 0x6) == 0x4) -#define IS_VALID_PIECE(p) ((PIECE_TYPE((p)) >= PAWN) && \ - (PIECE_TYPE((p)) <= KING)) -#define IS_WHITE_PIECE(p) ((p) & WHITE) -#define IS_BLACK_PIECE(p) (!IS_WHITE(p)) -#define OPPOSITE_COLORS(p, q) (((p) ^ (q)) & WHITE) -#define SAME_COLOR(p,q) (!OPPOSITE_COLORS(p, q)) -#define GET_COLOR(p) ((p) & WHITE) - -// ---------------------------------------------------------------------- -// -// a coordinate (8 bits) = rank + file (0x88) -// -// 7 4 3 0 -// . . . . . . . . -// | | | -// rank file -// | | -// | +--- 0-7 = file A thru file H -// | -// +------------ 0-7 = rank 1 thru rank 8 -// -// given a coordinate, C, if C & 0x88 then it is illegal (off board) -// -// -// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 -// +---------------------------------------+ -// 8 | 00 |:01:| 02 |:03:| 04 |:05:| 06 |:07:| 0x00 -// 7 |:10:| 11 |:12:| 13 |:14:| 15 |:16:| 17 | 0x10 -// 6 | 20 |:21:| 22 |:23:| 24 |:25:| 26 |:27:| 0x20 -// 5 |:30:| 31 |:32:| 33 |:34:| 35 |:36:| 37 | 0x30 -// 4 | 40 |:41:| 42 |:43:| 44 |:45:| 46 |:47:| 0x40 -// 3 |:50:| 51 |:52:| 53 |:54:| 55 |:56:| 57 | 0x50 -// 2 | 60 |:61:| 62 |:63:| 64 |:65:| 66 |:67:| 0x60 -// 1 |:70:| 71 |:72:| 73 |:74:| 75 |:76:| 77 | 0x70 -// +---------------------------------------+ -// A B C D E F G H -// -#define A (0) -#define B (1) -#define C (2) -#define D (3) -#define E (4) -#define F (5) -#define G (6) -#define H (7) - -#define A8 (0x00) -#define B8 (0x01) -#define C8 (0x02) -#define D8 (0x03) -#define E8 (0x04) -#define F8 (0x05) -#define G8 (0x06) -#define H8 (0x07) - -#define A7 (0x10) -#define B7 (0x11) -#define C7 (0x12) -#define D7 (0x13) -#define E7 (0x14) -#define F7 (0x15) -#define G7 (0x16) -#define H7 (0x17) - -#define A6 (0x20) -#define B6 (0x21) -#define C6 (0x22) -#define D6 (0x23) -#define E6 (0x24) -#define F6 (0x25) -#define G6 (0x26) -#define H6 (0x27) - -#define A5 (0x30) -#define B5 (0x31) -#define C5 (0x32) -#define D5 (0x33) -#define E5 (0x34) -#define F5 (0x35) -#define G5 (0x36) -#define H5 (0x37) - -#define A4 (0x40) -#define B4 (0x41) -#define C4 (0x42) -#define D4 (0x43) -#define E4 (0x44) -#define F4 (0x45) -#define G4 (0x46) -#define H4 (0x47) - -#define A3 (0x50) -#define B3 (0x51) -#define C3 (0x52) -#define D3 (0x53) -#define E3 (0x54) -#define F3 (0x55) -#define G3 (0x56) -#define H3 (0x57) - -#define A2 (0x60) -#define B2 (0x61) -#define C2 (0x62) -#define D2 (0x63) -#define E2 (0x64) -#define F2 (0x65) -#define G2 (0x66) -#define H2 (0x67) - -#define A1 (0x70) -#define B1 (0x71) -#define C1 (0x72) -#define D1 (0x73) -#define E1 (0x74) -#define F1 (0x75) -#define G1 (0x76) -#define H1 (0x77) - -// TODO: if use this anywhere that matters, consider double loop -// and unrolling the inside loop to prevent the multiple -// continue for invalid squares -#define FOREACH_SQUARE(x) for((x) = (A8); (x) <= (H1); (x)++) - -#define IS_ON_BOARD(c) (!((c) & 0x88)) -#define RANDOM_COOR (rand() & 0x77) -#define FILE_RANK_TO_COOR(f, r) (((8 - (r)) << 4) | (f)) -#define RANK(c) (8 - ((c) >> 4)) -#define RANK1(c) (((c) & 0xF0) == 0x70) -#define RANK2(c) (((c) & 0xF0) == 0x60) -#define RANK3(c) (((c) & 0xF0) == 0x50) -#define RANK4(c) (((c) & 0xF0) == 0x40) -#define RANK5(c) (((c) & 0xF0) == 0x30) -#define RANK6(c) (((c) & 0xF0) == 0x20) -#define RANK7(c) (((c) & 0xF0) == 0x10) -#define RANK8(c) (((c) & 0xF0) == 0x00) -#define FILE(c) ((c) & 0x0F) -#define FILEA(c) (((c) & 0x0F) == 0x00) -#define FILEB(c) (((c) & 0x0F) == 0x01) -#define FILEC(c) (((c) & 0x0F) == 0x02) -#define FILED(c) (((c) & 0x0F) == 0x03) -#define FILEE(c) (((c) & 0x0F) == 0x04) -#define FILEF(c) (((c) & 0x0F) == 0x05) -#define FILEG(c) (((c) & 0x0F) == 0x06) -#define FILEH(c) (((c) & 0x0F) == 0x07) -#define IS_WHITE_SQUARE_FR(f, r) (((f) + (r) - 1) & 1) -#define IS_WHITE_SQUARE_COOR(c) (IS_WHITE_SQUARE_FR(FILE(c), RANK(c))) -#define VALID_EP_SQUARE(c) (((c) == ILLEGAL_COOR) || ((c) == 0) || \ - (RANK3(c)) || \ - (RANK6(c))) - -// ---------------------------------------------------------------------- -// -// a move (4 bytes) = from/to, moved, captured, promoted and special -// -// 31 24 23 16 15 12 11 8 7 4 3 0 -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -// | from | to | moved | capt | prom | flags | -// | | | | | -// | | | | | -// | | | | | -// | | +-------+-------+-- type and -// | | color of -// | | piece moved -// | | captured and -// | | promote targ -// +---------------+-- board location where -// move begins and ends -// -// -// Special flag asserted on special move types: -// -// if (special) -// { -// if (moved == PAWN) -// { -// if (promotion) -// { -// move is a promote (w/ or w/o capture) -// } -// else if (capture) -// { -// move is an en passant catpure -// } -// else -// { -// move is a double jump -// } -// } -// else if (moved == KING) -// { -// move is a castle (long or short) -// } -// else -// { -// invalid use of special flag -// } -// } -// -typedef union _MOVE -{ - ULONG uMove; - struct - { - UCHAR cFrom : 8; - UCHAR cTo : 8; - UCHAR pMoved : 4; - UCHAR pCaptured : 4; - UCHAR pPromoted : 4; - UCHAR bvFlags : 4; - }; -} MOVE; - -#define IS_SAME_MOVE(a, b) \ - (((a).uMove & 0x0FFFFFFF) == (((b).uMove & 0x0FFFFFFF))) - -#define MAKE_MOVE(from,to,piece,cap,prom,flags) \ - (((ULONG)(from)) | \ - ((ULONG)(to) << 8) | \ - ((ULONG)(piece) << 16) | \ - ((ULONG)(cap) << 20) | \ - ((ULONG)(prom) << 24) | \ - ((ULONG)(flags) << 28)) - -#define MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(from,to,piece,cap) \ - (((ULONG)(from)) | \ - ((ULONG)(to) << 8) | \ - ((ULONG)(piece) << 16) | \ - ((ULONG)(cap) << 20)) - -// -// Move flag values: -// -#define MOVE_FLAG_SPECIAL (1) // en pass, prom, castle, double -#define IS_SPECIAL_MOVE(mv) \ - ((mv).uMove & 0x10000000) - -#define IS_CASTLE(mv) \ - (IS_SPECIAL_MOVE(mv) && IS_KING((mv).pMoved)) - -#ifdef DEBUG -#define IS_PROMOTION(mv) \ - (IS_SPECIAL_MOVE(mv) && ((mv).pPromoted)) -#else -#define IS_PROMOTION(mv) \ - ((mv).pPromoted) -#endif - -#define IS_CAPTURE_OR_PROMOTION(mv) \ - ((mv).uMove & 0x0FF00000) - -#define IS_ENPASSANT(mv) \ - (IS_SPECIAL_MOVE(mv) && (mv.pCaptured) && !IS_PROMOTION(mv)) - -#define IS_DOUBLE_JUMP(mv) \ - (IS_SPECIAL_MOVE(mv) && !IS_CAPTURE_OR_PROMOTION(mv)) - -#define MOVE_FLAG_KILLERMATE (2) // killer mate -#define IS_KILLERMATE_MOVE(mv) ((mv).uMove & 0x20000000) - -#define MOVE_FLAG_ESCAPING_CHECK (4) // escaping check -#define IS_ESCAPING_CHECK(mv) ((mv).uMove & 0x40000000) - -#define MOVE_FLAG_CHECKING (8) // checking move -#define IS_CHECKING_MOVE(mv) ((mv).uMove & 0x80000000) - -// ---------------------------------------------------------------------- -// -// Move list -// -#define MAX_MOVE_LIST (MAX_MOVES_PER_GAME + MAX_PLY_PER_SEARCH) - -// ---------------------------------------------------------------------- - -#pragma pack(1) -typedef union _ATTACK_BITV -{ - ULONG uWholeThing; - struct - { - union - { - UCHAR uSmall; - struct - { - UCHAR uNumAttacks : 3; // 0..2 - UCHAR uKing : 1; // 4..7 - UCHAR uQueen : 1; - UCHAR uRook : 1; - UCHAR uMinor : 1; - UCHAR uPawn : 1; - } small; - }; - - // -------------------- - union - { - USHORT uBig; - struct - { - USHORT uKing : 1; // 8..23 - USHORT uQueens : 4; - USHORT uRooks : 4; - USHORT uMinors : 4; - USHORT uPawns : 2; - USHORT uUnusedFlag1 : 1; - } big; - }; - - // ------------------- - union - { - UCHAR uXray; - struct - { - UCHAR uNumXrays : 3; - UCHAR uUnusedFlag2 : 1; - UCHAR uQueen : 1; // 24..28 - UCHAR uRook : 1; - UCHAR uBishop : 1; - UCHAR uUnusedFlag3 : 1; - } xray; - }; - }; -} -ATTACK_BITV; - -#define UNSAFE_FOR_MINOR(x) ((ULONG)((x).uWholeThing) & 0x00000080UL) -#define UNSAFE_FOR_ROOK(x) ((ULONG)((x).uWholeThing) & 0x000000C0UL) -#define UNSAFE_FOR_QUEEN(x) ((ULONG)((x).uWholeThing) & 0x000000E0UL) - -#define PAWN_BIT 0x00000080UL -#define MINOR_BIT 0x00000040UL -#define MINOR_XRAY_BIT 0x40000000UL -#define ROOK_BIT 0x00000020UL -#define ROOK_XRAY_BIT 0x20000000UL -#define QUEEN_BIT 0x00000010UL -#define QUEEN_XRAY_BIT 0x10000000UL - -#define INVALID_PIECE_INDEX (17) -#define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX) - -typedef union _SQUARE -{ - struct - { - PIECE pPiece; - ULONG uIndex; - }; - ATTACK_BITV bvAttacks[2]; -} -SQUARE; -#pragma pack() - -// -// POSITION -// -typedef struct _POSITION -{ - SQUARE rgSquare[128]; // where the pieces are, - // also, the attack table - UINT64 u64NonPawnSig; // hash signature - UINT64 u64PawnSig; // pawn hash signature - ULONG uToMove; // whose turn? - ULONG uFifty; // 50 moves w/o progress = draw - FLAG fCastled[2]; // record when sides have castled - BITV bvCastleInfo; // who can castle how? - COOR cEpSquare; // en-passant capture square - - COOR cPawns[2][8]; // location of pawns on the board - ULONG uPawnMaterial[2]; // pawn material of each side - ULONG uPawnCount[2]; // number of pawns for each side - - COOR cNonPawns[2][16]; // location of pieces on the board - ULONG uNonPawnMaterial[2]; // piece material of each side - ULONG uNonPawnCount[2][8]; // number of non-pawns / type - // 0 and 1 are the sum, - // 2..6 are per PIECE_TYPE - - ULONG uWhiteSqBishopCount[2]; // num bishops on white squares - SCORE iMaterialBalance[2]; // material balance - - // temporary storage space for use in eval - COOR cTrapped[2]; - ULONG uArmyScaler[2]; - ULONG uClosedScaler; - SCORE iScore[2]; - SCORE iReducedMaterialDownScaler[2]; - SCORE iTempScore; - ULONG uMinMobility[2]; - COOR cPiece; - ULONG uMinorsAtHome[2]; - BITBOARD bb; - ULONG uPiecesPointingAtKing[2]; -} -POSITION; - -// -// Castling permission bitvector flags. -// -#define CASTLE_WHITE_SHORT (1) -#define CASTLE_WHITE_LONG (2) -#define WHITE_CAN_CASTLE \ - (CASTLE_WHITE_SHORT | CASTLE_WHITE_LONG) -#define CASTLE_BLACK_SHORT (4) -#define CASTLE_BLACK_LONG (8) -#define BLACK_CAN_CASTLE \ - (CASTLE_BLACK_SHORT | CASTLE_BLACK_LONG) -#define CASTLE_NONE_POSSIBLE (0) -#define CASTLE_ALL_POSSIBLE \ - (WHITE_CAN_CASTLE | BLACK_CAN_CASTLE) - -// ---------------------------------------------------------------------- -// -// Move stack -// -#define MAX_MOVE_STACK (MAX_PLY_PER_SEARCH * \ - MAX_MOVES_PER_PLY) - -// -// Main part of the move stack, triads of moves, their values and flags -// that denote where the values came from -// -#define MVF_MOVE_SEARCHED (1) -#define MVF_EXTEND_MOVE (2) -#define MVF_REDUCE_MOVE (4) -#define MVF_PRUNE_SUBTREE (8) - -typedef struct _MOVE_STACK_MOVE_VALUE_FLAGS -{ - SCORE iValue; - MOVE mv; - BITV bvFlags; -} -MOVE_STACK_MOVE_VALUE_FLAGS; - -typedef struct _KEY_POINTER -{ - int iPointer; - ULONG uKey; -} -KEY_POINTER; - -typedef union _GENERATOR_FLAGS -{ - struct { - UCHAR uMoveCount; - UCHAR uKingMoveCount; - UCHAR uCheckingPieces; - UCHAR uUnused; - }; - ULONG uAllGenFlags; -} -GENERATOR_FLAGS; - -// -// A move stack -// -typedef struct _MOVE_STACK -{ -#ifdef DEBUG - POSITION board[MAX_PLY_PER_SEARCH]; -#endif - // - // Unblocked squares map, used for check detection - // - ULONG uUnblockedKeyValue[MAX_PLY_PER_SEARCH]; - KEY_POINTER sUnblocked[MAX_PLY_PER_SEARCH][128]; - - // - // The main move list, a long series of moves, their values and some - // flag bits to tell search what the values are based upon. - // - MOVE_STACK_MOVE_VALUE_FLAGS mvf[MAX_MOVE_STACK]; - - // - // uBegin[ply] and uEnd[ply] specify the start and end of moves gen- - // erated for a position at ply distance from the root. - // - ULONG uPly; - ULONG uBegin[MAX_PLY_PER_SEARCH]; - ULONG uEnd[MAX_PLY_PER_SEARCH]; - MOVE mvHash[MAX_PLY_PER_SEARCH]; - GENERATOR_FLAGS sGenFlags[MAX_PLY_PER_SEARCH]; -} -MOVE_STACK; - -#define GENERATE_NO_MOVES \ - ctx->sMoveStack.uEnd[ctx->uPly] = \ - ctx->sMoveStack.uBegin[ctx->uPly] + 1; \ - ctx->sMoveStack.uBegin[ctx->uPly + 1] = \ - ctx->sMoveStack.uEnd[ctx->uPly] - -#define GENERATE_ALL_MOVES (1) -#define GENERATE_ESCAPES (2) -#define GENERATE_CAPTURES_PROMS_CHECKS (3) -#define GENERATE_CAPTURES_PROMS (4) -#define GENERATE_DONT_SCORE (5) -#ifdef TEST -#define GENERATE_ALL_MOVES_CHECK_OK (6) -#endif - -#define MOVE_COUNT(ctx, x) \ - (((ctx)->sMoveStack.uEnd[(x)]) - (ctx)->sMoveStack.uBegin[(x)]) -#define ONE_LEGAL_MOVE(ctx, x) \ - (MOVE_COUNT(ctx, x) == 1) -#define NUM_KING_MOVES(ctx, x) \ - ((ctx)->sMoveStack.sGenFlags[(x)].uKingMoveCount) -#define NUM_CHECKING_PIECES(ctx, x) \ - ((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces) - - -// ---------------------------------------------------------------------- -// -// Accumulators -// -typedef struct _COUNTERS -{ - struct - { - UINT64 u64Probes; - UINT64 u64OverallHits; - UINT64 u64UsefulHits; - UINT64 u64UpperBoundHits; - UINT64 u64LowerBoundHits; - UINT64 u64ExactScoreHits; - } - hash; - - struct - { - UINT64 u64Probes; - UINT64 u64Hits; - } - pawnhash; - - struct - { - UINT64 u64TotalNodeCount; - UINT64 u64QNodeCount; - UINT64 u64LeafCount; - UINT64 u64TerminalPositionCount; - UINT64 u64BetaCutoffs; - UINT64 u64BetaCutoffsOnFirstMove; - UINT64 u64NullMoves; - UINT64 u64NullMoveSuccess; -#ifdef TEST_NULL - UINT64 u64QuickNullSuccess; - UINT64 u64QuickNullDeferredSuccess; - UINT64 u64QuickNullFailures; - UINT64 u64AvoidNullSuccess; - UINT64 u64AvoidNullFailures; -#endif - UINT64 u64EvalHashHits; - UINT64 u64LazyEvals; - UINT64 u64FullEvals; - UINT64 u64CyclesInEval; - } - tree; - - struct - { - ULONG uNumSplits; - ULONG uNumSplitsTerminated; - } - parallel; - - struct - { - ULONG uPawnPush; - ULONG uCheck; - ULONG uMateThreat; - ULONG uRecapture; - ULONG uOneLegalMove; - ULONG uNoLegalKingMoves; - ULONG uMultiCheck; - ULONG uSingularMove; - ULONG uZugzwang; - ULONG uSingularReplyToCheck; - ULONG uEndgame; - ULONG uBotvinnikMarkoff; - ULONG uQExtend; - } - extension; - - struct - { - ULONG uProbes; - ULONG uHits; - } - egtb; -} -COUNTERS; - -typedef struct _CUMULATIVE_SEARCH_FLAGS -{ - // search - ULONG uNumChecks[2]; // not used - FLAG fInSuspiciousBranch; // not used - FLAG fInReducedDepthBranch; // not used - FLAG fAvoidNullmove; // restore - FLAG fVerifyNullmove; // restore - - // qsearch - ULONG uQsearchDepth; // restore - ULONG uQsearchNodes; // incremental - ULONG uQsearchCheckDepth; // restore - FLAG fCouldStandPat[2]; // restore -} -CUMULATIVE_SEARCH_FLAGS; - -// ---------------------------------------------------------------------- -// -// Searcher thread record -// -typedef struct _SPLIT_INFO -{ - // locks / counters - volatile ULONG uLock; // lock for this split node - volatile ULONG uNumThreadsHelping; // num threads in this node - volatile FLAG fTerminate; // signal helpers to terminate - - // moves in the split node - ULONG uRemainingMoves; // num moves remaining to do - ULONG uOnDeckMove; // next move to do - ULONG uNumMoves; - ULONG uAlreadyDone; - MOVE_STACK_MOVE_VALUE_FLAGS - mvf[MAX_MOVES_PER_PLY]; // the moves to search - - // input to the split node - POSITION sRootPosition; // the root position - MOVE mvPathToHere[MAX_PLY_PER_SEARCH]; // path from root to split - MOVE mvLast; // last move before split - ULONG uDepth; // remaining depth at split - INT iPositionExtend; // positional extension - SCORE iAlpha; // original alpha at split - SCORE iBeta; // beta at split - ULONG uSplitPositional; // pos->uPositional at split - CUMULATIVE_SEARCH_FLAGS sSearchFlags; // flags at split time - - // output from the split node - MOVE mvBest; // the best move - SCORE iBestScore; // it's score - COUNTERS sCounters; // updated counters - MOVE PV[MAX_PLY_PER_SEARCH]; - -#ifdef DEBUG - ULONG uSplitPly; - POSITION sSplitPosition; -#endif -} -SPLIT_INFO; - -typedef struct _PLY_INFO -{ -#ifdef DEBUG - POSITION sPosition; - SCORE iAlpha; - SCORE iBeta; -#endif - SCORE iEval; - INT iExtensionAmount; - FLAG fInCheck; - FLAG fInQsearch; - MOVE mv; - MOVE mvBest; - MOVE PV[MAX_PLY_PER_SEARCH]; - - SCORE iKingScore[2]; - ULONG uMinMobility[2]; - UINT64 u64NonPawnSig; - UINT64 u64PawnSig; - UINT64 u64Sig; - ULONG uFifty; - FLAG fCastled[2]; - ULONG uTotalNonPawns; - BITV bvCastleInfo; - COOR cEpSquare; -} -PLY_INFO; - -#define EVAL_HASH -#ifdef EVAL_HASH -#define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread) -typedef struct _EVAL_HASH_ENTRY -{ - UINT64 u64Key; - SCORE iEval; - ULONG uPositional; - COOR cTrapped[2]; - -} EVAL_HASH_ENTRY; -#endif - -#define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread) -typedef struct _PAWN_HASH_ENTRY -{ - UINT64 u64Key; - BITBOARD bbPawnLocations[2]; - BITBOARD bbPasserLocations[2]; - BITBOARD bbStationaryPawns[2]; - SHORT iScore[2]; - UCHAR uCountPerFile[2][10]; - UCHAR uNumRammedPawns; - UCHAR uNumUnmovedPawns[2]; -} -PAWN_HASH_ENTRY; - -#define NUM_SPLIT_PTRS_IN_CONTEXT (8) - -typedef struct _SEARCHER_THREAD_CONTEXT -{ - ULONG uPly; // its distance from root - ULONG uPositional; // positional component of score - POSITION sPosition; // the board - MOVE_STACK sMoveStack; // the move stack - CUMULATIVE_SEARCH_FLAGS sSearchFlags; - PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; - MOVE mvKiller[MAX_PLY_PER_SEARCH][2]; - MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2]; - MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH]; - COUNTERS sCounters; - ULONG uThreadNumber; - SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT]; - MOVE mvRootMove; - SCORE iRootScore; - ULONG uRootDepth; - PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE]; -#ifdef EVAL_HASH - EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE]; -#endif - CHAR szLastPV[SMALL_STRING_LEN_CHAR]; -} -SEARCHER_THREAD_CONTEXT; - -// -// When I added the pawn hash table and eval hash tables to searcher -// thread contexts they became too heavy to just allocate on the fly -// for things like checking the legality of SAN moves or seeing if an -// opening book line leads to a draw. This -// LIGHTWEIGHT_SEARCHER_CONTEXT structure can be cast into a full -// SEARCHER_THREAD_CONTEXT and passed safely into the Generate, -// MakeMove and UnMakeMove functions because they presently only -// need: -// -// 1. uPly -// 2. sPosition -// 3. sPlyInfo -// 4. sMoveStack -// -typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT -{ - ULONG uPly; - ULONG uPositional; - POSITION sPosition; - MOVE_STACK sMoveStack; - CUMULATIVE_SEARCH_FLAGS sSearchFlags; - PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; -} -LIGHTWEIGHT_SEARCHER_CONTEXT; - -// ---------------------------------------------------------------------- -// -// Global game options -// -typedef struct _GAME_OPTIONS -{ - ULONG uMyClock; - ULONG uOpponentsClock; - FLAG fGameIsRated; - FLAG fOpponentIsComputer; - ULONG uSecPerMove; - ULONG uMaxDepth; - FLAG fShouldPonder; - FLAG fPondering; - FLAG fThinking; - FLAG fSuccessfulPonder; - MOVE mvPonder; - FLAG fShouldPost; - FLAG fForceDrawWorthZero; - ULONG uMyIncrement; - ULONG uMovesPerTimePeriod; - CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR]; - FLAG fShouldAnnounceOpening; - SCORE iLastEvalScore; - UINT64 u64NodesSearched; - CHAR szLogfile[SMALL_STRING_LEN_CHAR]; - CHAR szEGTBPath[SMALL_STRING_LEN_CHAR]; - CHAR szBookName[SMALL_STRING_LEN_CHAR]; - ULONG uNumProcessors; - ULONG uNumHashTableEntries; - FLAG fNoInputThread; - FLAG fVerbosePosting; - FLAG fRunningUnderXboard; - FLAG fStatusLine; - FLAG fFastScript; - - enum - { - CLOCK_NORMAL = 0, - CLOCK_FIXED, - CLOCK_INCREMENT, - CLOCK_NONE - } - eClock; - - enum - { - GAME_UNKNOWN = 0, - GAME_BULLET, - GAME_BLITZ, - GAME_STANDARD - } - eGameType; - - enum - { - I_PLAY_WHITE = 0, - I_PLAY_BLACK, - FORCE_MODE, - EDIT_MODE, - ANALYZE_MODE - } - ePlayMode; -} -GAME_OPTIONS; -extern GAME_OPTIONS g_Options; - -// ---------------------------------------------------------------------- -// -// Move timer -// - -#define TIMER_SEARCHING_FIRST_MOVE (0x1) -#define TIMER_SEARCHING_IMPORTANT_MOVE (0x2) -#define TIMER_RESOLVING_ROOT_FL (0x4) -#define TIMER_RESOLVING_ROOT_FH (0x8) -#define TIMER_JUST_OUT_OF_BOOK (0x10) -#define TIMER_CURRENT_OBVIOUS (0x20) -#define TIMER_CURRENT_WONT_UNBLOCK (0x40) -#define TIMER_ROOT_POSITION_CRITICAL (0x80) -#define TIMER_MOVE_IMMEDIATELY (0x100) -#define TIMER_MANY_ROOT_FLS (0x200) -#define TIMER_STOPPING (0x400) -#define TIMER_SPLIT_FAILED (0x800) - -typedef struct _MOVE_TIMER -{ - double dStartTime; - double dEndTime; - double dSoftTimeLimit; - double dHardTimeLimit; - ULONG uNodeCheckMask; - volatile BITV bvFlags; -} -MOVE_TIMER; - -// ---------------------------------------------------------------------- -// -// Special move tag literals -// -#define ILLEGALMOVE ((ULONG)0x1DDD8888) - -// -// useful macros -// -#ifdef DEBUG -void -_assert(CHAR *szFile, ULONG uLine); - -#define ASSERT(x) if (x) \ - { ; } \ - else \ - { _assert(__FILE__, __LINE__); } -#define VERIFY(x) ASSERT(x) -#else -#define ASSERT(x) ; -#define VERIFY(x) x; -#endif // DEBUG - -#ifdef PERF_COUNTERS -#define INC(x) ((x) += 1) -#else -#define INC(x) -#endif - -#define BREAKPOINT SystemDebugBreakpoint() - -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) - -#ifdef _X86_ -// -// Note: MAXU, MINU and ABS_DIFF require arguments with the high order -// bit CLEAR to work right. -// -// These are branchless constructs. MAXU and MINU are equivalent to -// MIN and MAX (with the above restriction on inputs) -// -// MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x). These -// macros have no restiction on argument type. -// -// ABS_DIFF is equivalent to abs(x - y). Again, x and y must have -// their high-order bits CLEAR for this to work. -// -// Note: gcc generates code with cmovs so no need for MAXU/MINU on -// that compiler. -// -//#ifndef __GNUC__ -#define MINU(x, y) \ - (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y)) -#define MAXU(x, y) \ - (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x)) -//#endif -#ifndef DEBUG - -#define MIN0(x) \ - ((x) & (((int)(x)) >> 31)) - -#define MAX0(x) \ - ((x) & ~(((int)(x)) >> 31)) - -#else // !DEBUG -extern INLINE int MIN0(int x) -{ - int y = MIN(x, 0); - int z = ((x) & (((int)(x)) >> 31)); - ASSERT(y == z); - return(z); -} - -extern INLINE int MAX0(int x) -{ - int y = MAX(x, 0); - int z = ((x) & ~(((int)(x)) >> 31)); - ASSERT(y == z); - return(z); -} -#endif // DEBUG - -#define ABS_DIFF(a, b) \ - (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1)) - -#endif // _X86_ - -#ifndef MINU -#define MINU(x, y) (MIN((x), (y))) -#endif - -#ifndef MAXU -#define MAXU(x, y) (MAX((x), (y))) -#endif - -#ifndef MIN0 -#define MIN0(x) (MIN((x), 0)) -#endif - -#ifndef MAX0 -#define MAX0(x) (MAX((x), 0)) -#endif - -#ifndef ABS_DIFF -#define ABS_DIFF(a, b) (abs((a) - (b))) -#endif - -#define FILE_DISTANCE(a, b) (ABS_DIFF(FILE((a)), FILE((b)))) -#define RANK_DISTANCE(a, b) (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4) -#define REAL_DISTANCE(a, b) (MAXU(FILE_DISTANCE((a), (b)), \ - RANK_DISTANCE((a), (b)))) -#ifdef DEBUG -#define DISTANCE(a, b) DistanceBetweenSquares((a), (b)) -#else -#define DISTANCE(a, b) g_pDistance[(a) - (b)] -#endif // DEBUG - -#define IS_EMPTY( square ) (!(square)) -#define IS_OCCUPIED( square ) ((square)) - -#define IS_DEAD( listindex ) ((listindex) > 119) -#define IS_ALIVE( listindex ) ((listindex) <= 119) -#define ILLEGAL_COOR (0x88) -#define EDGE_DISTANCE(c) (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \ - MIN(abs(FILE(c) - 7), FILE(c)))) -#define NOT_ON_EDGE(c) ((((c) & 0xF0) != 0x00) && \ - (((c) & 0xF0) != 0x70) && \ - (((c) & 0x0F) != 0x00) && \ - (((c) & 0x0F) != 0x07)) -#define ON_EDGE(c) (RANK8(c) || \ - RANK1(c) || \ - FILEA(c) || \ - FILEH(c)) -#define CORNER_DISTANCE(c) (MAX(MIN((ULONG)abs(RANK(c) - 7), RANK(c)),\ - MIN((ULONG)abs(FILE(c) - 7), FILE(c)))) -#define IN_CORNER(c) (((c) == A8) || \ - ((c) == A1) || \ - ((c) == H8) || \ - ((c) == H1)) -#define WHITE_CORNER_DISTANCE(c) (MIN(DISTANCE((c), A8), \ - DISTANCE((c), H1))) -#define BLACK_CORNER_DISTANCE(c) (MIN(DISTANCE((c), H8), \ - DISTANCE((c), A1))) -#define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \ - | (7 - ((c) & 0x0F)) -#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a[0]))) -#define MAKE_PSQT(a, b, c, d) (((a) << 24) | ((b) << 16) | \ - ((c) << 8) | (d)) -#define TO64(x) ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3) -#define COOR_TO_BIT_NUMBER(c) (((((c) & 0x70) >> 1) | ((c) & 0x7))) -#define SLOWCOOR_TO_BB(c) (1ULL << COOR_TO_BIT_NUMBER(c)) -#define COOR_TO_BB(c) (BBSQUARE[COOR_TO_BIT_NUMBER(c)]) -#define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7)) -#define BIT_NUMBER_TO_COOR(b) ((((b) & 0xF8) << 1) | ((b) & 7)) - -#define BBRANK88 \ - SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \ - SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \ - SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8) - -#define BBRANK77 \ - SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \ - SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \ - SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7) - -#define BBRANK66 \ - SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \ - SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \ - SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6) - -#define BBRANK55 \ - SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \ - SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \ - SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5) - -#define BBRANK44 \ - SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \ - SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \ - SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4) - -#define BBRANK33 \ - SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \ - SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \ - SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3) - -#define BBRANK22 \ - SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \ - SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \ - SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2) - -#define BBRANK11 \ - SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \ - SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \ - SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1) - -#define BBFILEA \ - SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \ - SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \ - SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8) - -#define BBFILEB \ - SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \ - SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \ - SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8) - -#define BBFILEC \ - SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \ - SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \ - SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8) - -#define BBFILED \ - SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \ - SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \ - SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8) - -#define BBFILEE \ - SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \ - SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \ - SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8) - -#define BBFILEF \ - SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \ - SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \ - SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8) - -#define BBFILEG \ - SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \ - SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \ - SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8) - -#define BBFILEH \ - SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \ - SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \ - SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8) - -#define BBRANK72 \ - BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 - -#define BBRANK62 \ - BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 - -#define BBRANK52 \ - BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 - -#define BBRANK42 \ - BBRANK44 | BBRANK33 | BBRANK22 - -#define BBRANK32 \ - BBRANK33 | BBRANK22 - -#define BBRANK27 \ - BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 - -#define BBRANK37 \ - BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 - -#define BBRANK47 \ - BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 - -#define BBRANK57 \ - BBRANK55 | BBRANK66 | BBRANK77 - -#define BBRANK67 \ - BBRANK66 | BBRANK77 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// util.c -// -COMMAND(LearnPsqtFromPgn); - -COMMAND(GeneratePositionAndBestMoveSuite); - -CHAR * -WalkPV(SEARCHER_THREAD_CONTEXT *ctx); - -CHAR * -ReadNextGameFromPgnFile(FILE *pf); - -COOR -DistanceBetweenSquares(COOR a, COOR b); - -void CDECL -Trace(CHAR *szMessage, ...); - -void CDECL -Log(CHAR *szMessage, ...); - -void CDECL -Bug(CHAR *szMessage, ...); - -char * -FindChunk(char *sz, ULONG uTargetChunk); - -FLAG -BufferIsZeroed(BYTE *p, ULONG u); - -char * -ColorToString(ULONG u); - -char * -CoorToString(COOR c); - -char * -ScoreToString(SCORE iScore); - -char * -TimeToString(double d); - -ULONG -AcquireSpinLock(volatile ULONG *pSpinlock); - -FLAG -TryAcquireSpinLock(volatile ULONG *pSpinlock); - -void -ReleaseSpinLock(volatile ULONG *pSpinLock); - -BYTE -Checksum(BYTE *p, ULONG uSize); - -FLAG -BackupFile(CHAR *szFile); - -void -UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, - SCORE iAlpha, - SCORE iBeta, - SCORE iScore, - MOVE mv); - -#define CANNOT_INITIALIZE_SPLIT (1) -#define INCONSISTENT_POSITION (2) -#define UNEXPECTED_SYSTEM_CALL_FAILURE (3) -#define SHOULD_NOT_GET_HERE (4) -#define GOT_ILLEGAL_MOVE_WHILE_PONDERING (5) -#define CANNOT_OFFICIALLY_MAKE_MOVE (6) -#define DETECTED_INCORRECT_INITIALIZATION (7) -#define INCONSISTENT_STATE (8) -#define FATAL_ACCESS_DENIED (9) -#define TESTCASE_FAILURE (10) -#define INITIALIZATION_FAILURE (11) - -void -UtilPanic(ULONG uPanicCode, - POSITION *pos, - void *a1, - void *a2, - void *a3, - char *file, ULONG line); - - -// -// main.c -// -#define LOGFILE_NAME "typhoon.log" -extern FILE *g_pfLogfile; - -void -Banner(void); - -FLAG -PreGameReset(FLAG fResetBoard); - -// -// system dependent exports (see win32.c or fbsd.c) -// -typedef ULONG (THREAD_ENTRYPOINT)(ULONG); - -#ifdef DEBUG -ULONG -GetHeapMemoryUsage(void); -#endif - -void -SystemDebugBreakpoint(void); - -CHAR * -SystemStrDup(CHAR *p); - -double -SystemTimeStamp(void); - -FLAG -SystemDoesFileExist(CHAR *szFilename); - -void -SystemDeferExecution(ULONG uMs); - -void -SystemFreeMemory(void *pMem); - -void * -SystemAllocateMemory(ULONG dwSizeBytes); - -FLAG -SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes); - -FLAG -SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes); - -FLAG -SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes); - -FLAG -SystemDependentInitialization(void); - -UINT64 FASTCALL -SystemReadTimeStampCounter(void); - -// -// This routine _must_ implement a full memory fence -- it is used in -// util.c to implement spinlocks. -// -FLAG -SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle); - -FLAG -SystemWaitForThreadToExit(ULONG uThreadHandle); - -FLAG -SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode); - -FLAG -SystemDeleteThread(ULONG uThreadHandle); - -CHAR * -SystemGetDateString(void); - -CHAR * -SystemGetTimeString(void); - -FLAG -SystemCopyFile(CHAR *szSource, CHAR *szDest); - -FLAG -SystemDeleteFile(CHAR *szFile); - -ULONG -SystemCreateLock(void); - -FLAG -SystemDeleteLock(ULONG u); - -FLAG -SystemBlockingWaitForLock(ULONG u); - -FLAG -SystemReleaseLock(ULONG u); - -ULONG -SystemCreateSemaphore(ULONG u); - -FLAG -SystemDeleteSemaphore(ULONG u); - -void -SystemReleaseSemaphoreResource(ULONG u); - -void -SystemObtainSemaphoreResource(ULONG u); - - -// -// fen.c -// -#define STARTING_POSITION_IN_FEN \ - "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1" - -FLAG -LooksLikeFen(char *szFen); - -char * -PositionToFen(POSITION *p); - -FLAG -FenToPosition(POSITION *p, char *szFen); - -// -// testfen.c -// -#ifdef TEST -void -TestFenCode(void); -#endif - -// -// piece.c -// -// INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN; -#define VALUE_PAWN 100 -#define INVERT_PAWN 900 -#define VALUE_KNIGHT 300 -#define INVERT_KNIGHT 300 -#define VALUE_BISHOP 300 -#define INVERT_BISHOP 300 -#define VALUE_ROOK 500 -#define INVERT_ROOK 180 -#define VALUE_QUEEN 975 -#define INVERT_QUEEN 100 -#define VALUE_KING (INFINITY) -#define INVERT_KING 1 - -#define VALUE_FULL_ARMY (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \ - (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ - VALUE_QUEEN + VALUE_KING -#define VALUE_MAX_ARMY (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \ - (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ - VALUE_KING - -typedef struct _PIECE_DATA -{ - ULONG uValue; - ULONG uValueOver100; - ULONG uInvertedValue; - CHAR *szName; -} PIECE_DATA; - -extern PIECE_DATA g_PieceData[8]; - -#define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100) -extern ULONG -PieceValueOver100(PIECE p); - -#define PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uValue) -extern ULONG -PieceValue(PIECE p); - -#define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue) -extern ULONG -PieceInvertedValue(PIECE p); - -CHAR * -PieceAbbrev(PIECE p); - -// -// board.c -// -FLAG -VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError); - -FLAG -PositionsAreEquivalent(POSITION *p1, POSITION *p2); - -CHAR * -DrawTextBoardFromPosition(POSITION *pos); - -void -DumpPosition(POSITION *pos); - -CHAR * -CastleInfoString(BITV bv); - -void -SetRootToInitialPosition(void); - -// -// move.c -// -void -SlidePiece(POSITION *pos, COOR cFrom, COOR cTo); - -PIECE -LiftPiece(POSITION *pos, COOR cSquare); - -void -PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece); - -FLAG -MakeMove(SEARCHER_THREAD_CONTEXT *ctx, - MOVE mv); - -void -UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx, - MOVE mv); - -FLAG -MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser); - -void -DumpMove(ULONG u); - -// -// movesup.c -// -#define MOVE_TO_INDEX(mv) (((mv).uMove & 0xFFFF) + \ - (0x10000 * GET_COLOR(mv.pMoved))) - -COOR -FasterExposesCheck(POSITION *pos, - COOR cRemove, - COOR cLocation); - -COOR -ExposesCheck(POSITION *pos, - COOR cRemove, - COOR cLocation); - -COOR -ExposesCheckEp(POSITION *pos, - COOR cTest, - COOR cIgnore, - COOR cBlock, - COOR cKing); - -FLAG -IsAttacked(COOR cTest, POSITION *pos, ULONG uSide); - -FLAG -InCheck(POSITION *pos, ULONG uSide); - -FLAG -SanityCheckMove(POSITION *pos, MOVE mv); - -FLAG -LooksLikeFile(CHAR c); - -FLAG -LooksLikeRank(CHAR c); - -FLAG -LooksLikeCoor(CHAR *szData); - -CHAR * -StripMove(CHAR *szMove); - -ULONG -LooksLikeMove(CHAR *szData); - -void FASTCALL -SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); - -void FASTCALL -SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); - -void FASTCALL -SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); - -#define NOT_MOVE 0 -#define MOVE_ICS 1 -#define MOVE_SAN 2 - -COMMAND(PerftCommand); - - -// -// testmove.c -// -#ifdef TEST -void -TestLiftPlaceSlidePiece(void); - -void -TestExposesCheck(void); - -void -TestIsAttacked(void); - -void -TestMakeUnmakeMove(void); -#endif - -// -// generate.c -// -#define SORT_THESE_FIRST (0x40000000) -#define FIRST_KILLER (0x20000000) -#define SECOND_KILLER (0x10000000) -#define THIRD_KILLER (0x08000000) -#define FOURTH_KILLER (0x04000000) -#define GOOD_MOVE (0x02000000) -#define STRIP_OFF_FLAGS (0x00FFFFFF) - -extern const int g_iQKDeltas[9]; -extern const int g_iNDeltas[9]; -extern const int g_iBDeltas[5]; -extern const int g_iRDeltas[5]; - -void -GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx, - MOVE mvOrderFirst, - ULONG uType); - -FLAG -WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx, - IN MOVE mv); - -// -// testgenerate.c -// -#ifdef TEST - -void -PlyTest(SEARCHER_THREAD_CONTEXT *ctx, - ULONG uDepth, - FLAG fRootPositionInCheck); - -void -TestMoveGenerator(void); - -void -TestLegalMoveGenerator(void); - -#endif - -// -// sig.c -// -extern UINT64 g_u64SigSeeds[128][7][2]; -extern UINT64 g_u64PawnSigSeeds[128][2]; -extern UINT64 g_u64CastleSigSeeds[16]; -extern UINT64 g_u64EpSigSeeds[9]; - -void -InitializeSigSystem(void); - -UINT64 -ComputePawnSig(POSITION *pos); - -UINT64 -ComputeSig(POSITION *pos); - -// -// mersenne.c -// -void -seedMT(unsigned int seed); - -unsigned int -reloadMT(void); - -unsigned int -randomMT(void); - -// -// data.c -// -typedef struct _VECTOR_DELTA -{ - UCHAR iVector[2]; - signed char iDelta; - signed char iNegDelta; -} -VECTOR_DELTA; - -extern ULONG g_uDistance[256]; -extern ULONG *g_pDistance; -extern VECTOR_DELTA g_VectorDelta[256]; -extern VECTOR_DELTA *g_pVectorDelta; -extern CHAR g_SwapTable[14][32][32]; -extern SCORE _PSQT[14][128]; -extern ULONG g_uSearchSortLimits[]; -extern MOVE NULLMOVE; -extern MOVE HASHMOVE; -extern MOVE RECOGNMOVE; -extern MOVE DRAWMOVE; -extern MOVE MATEMOVE; -extern FLAG g_fIsWhiteSquare[128]; -extern BITBOARD BBFILE[8]; -extern BITBOARD BBRANK[9]; -extern BITBOARD BBWHITESQ; -extern BITBOARD BBBLACKSQ; -extern BITBOARD BBLEFTSIDE; -extern BITBOARD BBRIGHTSIDE; -extern BITBOARD BBSQUARE[64]; -extern BITBOARD BBROOK_PAWNS; -extern BITBOARD BBPRECEEDING_RANKS[8][2]; -extern BITBOARD BBADJACENT_FILES[8]; -extern BITBOARD BBADJACENT_RANKS[9]; - -void -InitializeWhiteSquaresTable(void); - -void -InitializeVectorDeltaTable(void); - -void -InitializeSwapTable(void); - -void -InitializeDistanceTable(void); - -void -InitializeSearchDepthArray(void); - -ULONG -GetSearchSortLimit(ULONG); - -#ifdef DEBUG -#define SEARCH_SORT_LIMIT(x) (GetSearchSortLimit((x))) -#else -#define SEARCH_SORT_LIMIT(x) (g_uSearchSortLimits[(x)]) -#endif - -#ifdef DEBUG -ULONG CheckVectorWithIndex(int i, ULONG uColor); -#define CHECK_VECTOR_WITH_INDEX(i, color) \ - CheckVectorWithIndex(i, color) - -int DirectionBetweenSquaresWithIndex(int i); -#define CHECK_DELTA_WITH_INDEX(i) \ - DirectionBetweenSquaresWithIndex(i) - -int DirectionBetweenSquaresFromTo(COOR, COOR); -#define DIRECTION_BETWEEN_SQUARES(from, to) \ - DirectionBetweenSquaresFromTo(from, to) - -int NegativeDirectionBetweenSquaresWithIndex(int i); -#define NEG_DELTA_WITH_INDEX(i) \ - NegativeDirectionBetweenSquaresWithIndex(i) - -FLAG IsSquareWhite(COOR c); -#define IS_SQUARE_WHITE(c) \ - IsSquareWhite(c) - -#else -#define CHECK_VECTOR_WITH_INDEX(i, color) \ - (g_pVectorDelta[(i)].iVector[(color)]) - -#define CHECK_DELTA_WITH_INDEX(i) \ - (g_pVectorDelta[(i)].iDelta) - -#define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \ - CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo)) - -#define NEG_DELTA_WITH_INDEX(i) \ - (g_pVectorDelta[(i)].iNegDelta) - -#define IS_SQUARE_WHITE(c) \ - (g_fIsWhiteSquare[(c)]) -#endif - -// -// san.c -// -MOVE -ParseMoveSan(CHAR *szInput, - POSITION *pos); - -CHAR * -MoveToSan(MOVE mv, POSITION *pos); - -// -// testsan.c -// -void -TestSan(void); - -// -// list.c -// -void -InitializeListHead(IN DLIST_ENTRY *pListHead); - -FLAG -IsListEmpty(IN DLIST_ENTRY *pListHead); - -FLAG -RemoveEntryList(IN DLIST_ENTRY *pEntry); - -DLIST_ENTRY * -RemoveHeadList(IN DLIST_ENTRY *pListHead); - -DLIST_ENTRY * -RemoveTailList(IN DLIST_ENTRY *pListHead); - -void -InsertTailList(IN DLIST_ENTRY *pListHead, - IN DLIST_ENTRY *pEntry); - -void -InsertHeadList(IN DLIST_ENTRY *pListHead, - IN DLIST_ENTRY *pEntry); - -// -// command.c -// -void -ParseUserInput(FLAG fSearching); - -FLAG -InitializeCommandSystem(void); - -void -CleanupCommandSystem(void); - -// -// input.c -// -void -InitInputSystemInBatchMode(void); - -ULONG -InitInputSystemWithDedicatedThread(void); - -void -PushNewInput(CHAR *buf); - -CHAR * -PeekNextInput(void); - -CHAR * -ReadNextInput(void); - -CHAR * -BlockingReadInput(void); - -ULONG -NumberOfPendingInputEvents(void); - -volatile extern FLAG g_fExitProgram; - -// -// ics.c -// -MOVE -ParseMoveIcs(CHAR *szInput, POSITION *pos); - -CHAR * -MoveToIcs(MOVE mv); - -// -// testics.c -// -void -TestIcs(void); - -// -// gamelist.c -// -typedef enum _ERESULT -{ - RESULT_BLACK_WON = -1, - RESULT_DRAW = 0, - RESULT_WHITE_WON = 1, - RESULT_IN_PROGRESS, - RESULT_ABANDONED, - RESULT_UNKNOWN -} -ERESULT; - -typedef struct _GAME_PLAYER -{ - CHAR *szName; - CHAR *szDescription; - FLAG fIsComputer; - ULONG uRating; -} -GAME_PLAYER; - -typedef struct _GAME_HEADER -{ - CHAR *szGameDescription; - CHAR *szLocation; - GAME_PLAYER sPlayer[2]; - FLAG fGameIsRated; - UINT64 u64OpeningSig; - ERESULT eResult; - CHAR *szResultComment; - CHAR *szInitialFen; -} -GAME_HEADER; - -typedef struct _GAME_MOVE -{ - DLIST_ENTRY links; - ULONG uNumber; - MOVE mv; - CHAR *szComment; - CHAR *szDecoration; - CHAR *szMoveInSan; - CHAR *szMoveInIcs; - CHAR *szUndoPositionFen; - SCORE iMoveScore; - UINT64 u64PositionSigAfterMove; - UINT64 u64PositionSigBeforeMove; - volatile FLAG fInUse; -} -GAME_MOVE; - -typedef struct _GAME_DATA -{ - GAME_HEADER sHeader; - DLIST_ENTRY sMoveList; -} -GAME_DATA; - -extern GAME_DATA g_GameData; - -POSITION * -GetRootPosition(void); - -FLAG -SetRootPosition(CHAR *szFen); - -void -ResetGameList(void); - -ULONG -GetMoveNumber(ULONG uColor); - -void -SetGameResultAndDescription(ERESULT r, CHAR *sz); - -INT -GetGameResult(void); - -void -SetMyName(void); - -void -SetOpponentsName(CHAR *sz); - -void -SetMyRating(ULONG u); - -void -SetOpponentsRating(ULONG u); - -void -DumpGameList(void); - -void -TellGamelistThatIPlayColor(ULONG u); - -void -DumpPgn(void); - -FLAG -LoadPgn(CHAR *szPgn); - -ULONG -CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig); - -FLAG -DoesSigAppearInOfficialGameList(UINT64 u64Sig); - -FLAG -OfficiallyTakebackMove(void); - -FLAG -OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast); - -GAME_MOVE * -GetNthOfficialMoveRecord(ULONG n); - -void -MakeStatusLine(void); - -FLAG -IsLegalDrawByRepetition(void); - -// -// script.c -// -COMMAND(ScriptCommand); - -COMMAND(SolutionCommand); - -COMMAND(AvoidCommand); - -COMMAND(IdCommand); - -void -PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *); - -FLAG -CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth); - -FLAG -WeAreRunningASuite(void); - - -// -// vars.c -// -COMMAND(SetCommand); - -// -// root.c -// -extern ULONG g_uSoftExtendLimit; -extern ULONG g_uHardExtendLimit; -extern volatile MOVE_TIMER g_MoveTimer; -extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; - -#ifdef PERF_COUNTERS -#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) \ - ctx->sCounters.tree.u64BetaCutoffs++; \ - if (x) \ - { \ - ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\ - } -#else -#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) -#endif - -#define GAME_NOT_OVER 0 -#define GAME_WHITE_WON 1 -#define GAME_BLACK_WON 2 -#define GAME_DRAW_STALEMATE 3 -#define GAME_DRAW_REPETITION 4 -#define GAME_ONE_LEGAL_MOVE 5 -#define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6 - -FLAG -Think(POSITION *pos); - -FLAG -Ponder(POSITION *pos); - -FLAG -Iterate(SEARCHER_THREAD_CONTEXT *ctx); - -void -SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor); - -void -SetMoveTimerToThinkForever(void); - -void -ClearRootNodecountHash(void); - -// -// draw.c -// -FLAG -IsDraw(SEARCHER_THREAD_CONTEXT *ctx); - - -// -// search.c -// -#define QPLIES_OF_NON_CAPTURE_CHECKS (1) -#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100) -#define DO_IID -#define IID_R_FACTOR (TWO_PLY + HALF_PLY) - -#ifndef MP -#define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING) -#else -#define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \ - (ThreadUnderTerminatingSplit(ctx))) -#endif - -SCORE FASTCALL -QSearch(SEARCHER_THREAD_CONTEXT *ctx, - SCORE iAlpha, - SCORE iBeta); - -SCORE FASTCALL -Search(SEARCHER_THREAD_CONTEXT *ctx, - SCORE iAlpha, - SCORE iBeta, - ULONG uDepth); - - -// -// searchsup.c -// -SCORE -ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, - IN MOVE mv, - IN ULONG uMoveNum); - -FLAG -ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *); - -FLAG -WeShouldDoHistoryPruning(IN SCORE iRoughEval, - IN SCORE iAlpha, - IN SCORE iBeta, - IN SEARCHER_THREAD_CONTEXT *ctx, - IN ULONG uRemainingDepth, - IN ULONG uLegalMoves, - IN MOVE mv, - IN ULONG uMoveNum, - IN INT iExtend); - -FLAG -WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, - IN SCORE iAlpha, - IN SCORE iBeta, - IN SCORE iRoughEval, - IN ULONG uNullDepth); - -FLAG -TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx, - IN OUT FLAG *pfThreat, - IN SCORE iAlpha, - IN SCORE iBeta, - IN ULONG uNullDepth, - IN OUT INT *piOrigExtend, - OUT SCORE *piNullScore); - -void -UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv); - -FLAG -CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx); - -void -ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, - IN ULONG uGenFlags, - IN ULONG uMoveNum, - IN SCORE iRoughEval, - IN SCORE iAlpha, - IN OUT INT *piExtend, - IN OUT INT *piOrigExtend); - -void -ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, - IN SCORE iAlpha, - IN SCORE iBeta, - IN ULONG uMoveNum, - IN SCORE iRoughEval, - IN ULONG uDepth, - IN OUT INT *piExtend); - -SCORE -RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx, - IN ULONG uDepth, - IN SCORE iAlpha, - IN SCORE iBeta); - -FLAG -MateDistancePruningCutoff(IN ULONG uPly, - IN FLAG fInCheck, - IN OUT SCORE *piBestScore, - IN OUT SCORE *piAlpha, - IN OUT SCORE *piBeta); - -FLAG -CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx, - IN OUT SCORE *piAlpha, - IN OUT SCORE *piBeta, - IN OUT SCORE *piScore); - -ULONG -SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx, - IN INT uDepth); - -#define VERIFY_BEFORE (1) -#define VERIFY_AFTER (2) - -FLAG -SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx, - IN ULONG uCurrent, - IN ULONG uType); - - -// -// testsearch.c -// -FLAG -TestSearch(void); - -// -// see.c -// -#define SEE_HEAPS - -SCORE -SEE(POSITION *pos, - MOVE mv); - -typedef struct _SEE_THREESOME -{ - PIECE pPiece; - COOR cLoc; - ULONG uVal; -} SEE_THREESOME; - -typedef struct _SEE_LIST -{ - ULONG uCount; - SEE_THREESOME data[16]; -} -SEE_LIST; - -SCORE -ControlsSquareMinusPiece(ULONG uSide, - POSITION *pos, - COOR c, - COOR cIgnore); - -// -// testsee.c -// -SCORE -DebugSEE(POSITION *pos, - MOVE mv); - -void -TestGetAttacks(void); - -// -// hash.c -// -#define NUM_HASH_ENTRIES_PER_LINE 4 -#define HASH_FLAG_EXACT 0x1 -#define HASH_FLAG_LOWER 0x2 -#define HASH_FLAG_UPPER 0x4 -#define HASH_FLAG_VALID_BOUNDS 0x7 -#define HASH_FLAG_THREAT 0x8 -#define HASH_FLAG_DIRTY 0xF0 - -typedef struct _HASH_ENTRY -{ - MOVE mv; // 0 1 2 3 - UCHAR uDepth; // 4 - UCHAR bvFlags; // 5 ==> d d d d | thr up low exact - signed short iValue; // 6 7 - UINT64 u64Sig; // 8 9 A B C D E F == 16 bytes -} HASH_ENTRY; - -FLAG -InitializeHashSystem(void); - -void -CleanupHashSystem(void); - -void -ClearHashTable(void); - -void -DirtyHashTable(void); - -void -StoreLowerBound(MOVE mvBestMove, - POSITION *pos, - SCORE iValue, - ULONG uDepth, - FLAG fThreat); -void -StoreExactScore(MOVE mvBestMove, - POSITION *pos, - SCORE iValue, - ULONG uDepth, - FLAG fThreat, - ULONG uPly); - -void -StoreUpperBound(//MOVE mvBestMove, - POSITION *pos, - SCORE iValue, - ULONG uDepth, - FLAG fThreat); - -HASH_ENTRY * -HashLookup(SEARCHER_THREAD_CONTEXT *ctx, - ULONG uDepth, - ULONG uNextDepth, - SCORE iAlpha, - SCORE iBeta, - FLAG *pfThreat, - FLAG *pfAvoidNull, - MOVE *pHashMove, - SCORE *piScore); - -COOR -CheckHashForDangerSquare(POSITION *pos); - -MOVE -GetPonderMove(POSITION *pos); - -extern ULONG g_uHashTableSizeEntries; -extern ULONG g_uHashTableSizeBytes; -extern HASH_ENTRY *g_pHashTable; - -// -// testhash.c -// -void -AnalyzeFullHashTable(void); - -// -// positionhash.c -// -// IDEA: store "mate threat" flag in here? -// IDEA: store "king safety" numbers in here? -// -typedef struct _POSITION_HASH_ENTRY { - UINT64 u64Sig; - UCHAR cEnprise[2]; - UCHAR uEnpriseCount[2]; - UCHAR cTrapped[2]; -} POSITION_HASH_ENTRY; - -void -InitializePositionHashSystem(void); - -void -CleanupPositionHashSystem(void); - -void -StoreEnprisePiece(POSITION *pos, COOR cSquare); - -void -StoreTrappedPiece(POSITION *pos, COOR cSquare); - -COOR -GetEnprisePiece(POSITION *pos, ULONG uSide); - -ULONG -GetEnpriseCount(POSITION *pos, ULONG uSide); - -COOR -GetTrappedPiece(POSITION *pos, ULONG uSide); - -FLAG -SideCanStandPat(POSITION *pos, ULONG uSide); - -ULONG -ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide); - -ULONG -ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide); - -// -// pawnhash.c -// -#define COOR_TO_BIT(x) ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3) - -void -ClearPawnHashStats(void); - -void -ReportPawnHashStats(void); - -PAWN_HASH_ENTRY * -PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx); - -// -// eval.c -// -#define LAZY_EVAL -#define LAZE_EVAL_BASE_SCORE 10 -extern const int g_iAhead[2]; -extern const int g_iBehind[2]; - -ULONG -DNABufferSizeBytes(); - -char * -ExportEvalDNA(); - -FLAG -WriteEvalDNA(char *szFilename); - -FLAG -ImportEvalDNA(char *p); - -FLAG -ReadEvalDNA(char *szFilename); - - - -SCORE -Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE); - -FLAG -EvalPasserRaces(POSITION *, - PAWN_HASH_ENTRY *); - -ULONG -CountKingSafetyDefects(POSITION *pos, - ULONG uSide); - -// -// testeval.c -// -#ifdef EVAL_DUMP -void -TestEval(void); - -void -EvalTraceReport(void); - -void -EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage); - -SCORE -EvalSigmaForPiece(POSITION *pos, COOR c); - -void -EvalTraceClear(void); - -void -TestEvalWithSymmetry(void); - -#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ - (VAL) += (ADJ); \ - EvalTrace((COL), (PIE), (COO), (ADJ), (MESS)); -#else -#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ - (VAL) += (ADJ); -#endif - -// -// bitboard.c -// -void -InitializeBitboards(void); - -ULONG CDECL -SlowCountBits(BITBOARD bb); - -ULONG CDECL -DeBruijnFirstBit(BITBOARD bb); - -ULONG CDECL -SlowFirstBit(BITBOARD bb); - -ULONG CDECL -SlowLastBit(BITBOARD bb); - -COOR -CoorFromBitBoardRank8ToRank1(BITBOARD *pbb); - -COOR -CoorFromBitBoardRank1ToRank8(BITBOARD *pbb); - -// -// x86.asm -// -ULONG CDECL -CountBits(BITBOARD bb); - -ULONG CDECL -FirstBit(BITBOARD bb); - -ULONG CDECL -LastBit(BITBOARD bb); - -ULONG CDECL -LockCompareExchange(volatile void *pDest, - ULONG uExch, - ULONG uComp); - -ULONG CDECL -LockIncrement(volatile void *pDest); - -ULONG CDECL -LockDecrement(volatile void *pDest); - -FLAG CDECL -CanUseParallelOpcodes(); - -ULONG CDECL -ParallelCompareUlong(ULONG uComparand, void *pComparators); - -ULONG CDECL -ParallelCompareVector(void *pComparand, void *pComparators); - -void CDECL -GetAttacks(SEE_LIST *pList, - POSITION *pos, - COOR cSquare, - ULONG uSide); - -void CDECL -SlowGetAttacks(SEE_LIST *pList, - POSITION *pos, - COOR cSquare, - ULONG uSide); - -#ifdef _X86_ -// -// Note: this is most of the stuff that x86.asm assumes about the -// internal data structures. If any of this fails then either the -// assembly language code needs to be updated or you need to use the C -// version of the routine in see.c instead. -// -#define ASSERT_ASM_ASSUMPTIONS \ - ASSERT(VALUE_PAWN == 100); \ - ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \ - ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \ - ASSERT(sizeof(SEE_THREESOME) == 12); \ - ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \ - ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \ - ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \ - ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \ - ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \ - ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \ - ASSERT(sizeof(SQUARE) == 8); \ - ASSERT(sizeof(VECTOR_DELTA) == 4); \ - ASSERT(sizeof(g_VectorDelta) == 256 * 4); \ - ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \ - ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \ - ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \ - ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \ - ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0); -#else -#define ASSERT_ASM_ASSUMPTIONS -#endif - -// -// testbitboard.c -// -void -TestBitboards(void); - -// -// dynamic.c -// -extern ULONG g_HistoryCounters[14][128]; - -ULONG -GetMoveFailHighPercentage(MOVE mv); - -void -UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx, - ULONG uRemainingDepth, - MOVE mvBest, - SCORE iScore, - ULONG uCurrent); - -void -NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore); - -FLAG -InitializeDynamicMoveOrdering(void); - -void -CleanupDynamicMoveOrdering(void); - -void -ClearDynamicMoveOrdering(void); - -void -MaintainDynamicMoveOrdering(void); - -void -IncrementMoveHistoryCounter(MOVE mv, ULONG u); - -void -DecrementMoveHistoryCounter(MOVE mv, ULONG u); - -// -// split.c -// -extern volatile ULONG g_uNumHelpersAvailable; -extern ULONG g_uNumHelperThreads; - -FLAG -InitializeParallelSearch(void); - -FLAG -CleanupParallelSearch(void); - -void -ClearHelperThreadIdleness(void); - -void -DumpHelperIdlenessReport(void); - -SCORE -StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx, - IN OUT SCORE *piAlpha, - IN SCORE iBeta, - IN OUT SCORE *piBestScore, - IN OUT MOVE *pmvBest, - IN ULONG uMoveNum, - IN INT iPositionExtend, - IN ULONG uDepth); - -void -InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); - -void -ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); - -void -InitializeLightweightSearcherContext(POSITION *pos, - LIGHTWEIGHT_SEARCHER_CONTEXT *ctx); - -// -// book.c -// - -#define BOOK_PROBE_MISS_LIMIT (7) -#define FLAG_DISABLED (1) -#define FLAG_ALWAYSPLAY (2) -#define FLAG_DELETED (4) - -#define BOOKMOVE_SELECT_MOVE (1) -#define BOOKMOVE_DUMP (2) - -#pragma pack(4) -typedef struct _BOOK_ENTRY -{ - UINT64 u64Sig; // 8 bytes - UINT64 u64NextSig; // 8 bytes - MOVE mvNext; // 4 bytes - ULONG uWins; // 4 bytes - ULONG uDraws; // 4 bytes - ULONG uLosses; // 4 bytes - BITV bvFlags; // 4 bytes -} -BOOK_ENTRY; -#pragma pack() - -typedef struct _OPENING_NAME_MAPPING -{ - UINT64 u64Sig; - CHAR *szString; -} -OPENING_NAME_MAPPING; - -#define BOOK_EDITING_RECORD "bkedit.edt" -#define OPENING_LEARNING_FILENAME "bklearn.bin" - -typedef struct _OPENING_LEARNING_ENTRY -{ - UINT64 u64Sig; - ULONG uWhiteWins; - ULONG uDraws; - ULONG uBlackWins; -} -OPENING_LEARNING_ENTRY; - -FLAG -InitializeOpeningBook(void); - -void -ResetOpeningBook(void); - -void -CleanupOpeningBook(void); - -MOVE -BookMove(POSITION *pos, - BITV bvFlags); - -COMMAND(BookCommand); - -extern ULONG g_uBookProbeFailures; -extern FLAG g_fTournamentMode; -extern CHAR *g_szBookName; - -// -// bench.c -// -COMMAND(BenchCommand); - -// -// testdraw.c -// -void -TestDraw(void); - -// -// probe.c -// -FLAG -ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score); - -void -InitializeEGTB(void); - -void -CleanupEGTB(void); - -// -// dumptree.c -// -#ifdef DUMP_TREE - -void -InitializeTreeDump(void); - -void -CleanupTreeDump(void); - -void -DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx, - ULONG uDepth, - FLAG fIsQNode, - SCORE iAlpha, - SCORE iBeta); - -void -DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx, - FLAG fQNode, - SCORE iBestScore, - MOVE mvBestMove); - -void CDECL -DTTrace(ULONG uPly, CHAR *szMessage, ...); - -#define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__) - -#else - -#define DTTRACE(...) - -#define DTEnterNode(...) - -#define DTLeaveNode(...) - -#define InitializeTreeDump(...) - -#define CleanupTreeDump(...) - -#endif - -// -// testsup.c -// -FLAG -IsBoardLegal(POSITION *pos); - -void -GenerateRandomLegalPosition(POSITION *pos); - -void -GenerateRandomLegalSymetricPosition(POSITION *pos); - -// -// recogn.c -// -#define UNRECOGNIZED (0) -#define RECOGN_EXACT (1) -#define RECOGN_UPPER (2) -#define RECOGN_LOWER (3) -#define RECOGN_EGTB (4) - -void -InitializeInteriorNodeRecognizers(void); - -ULONG -RecognLookup(SEARCHER_THREAD_CONTEXT *ctx, - SCORE *piScore, - FLAG fProbeEGTB); - -#ifdef EVAL_HASH -void -ClearEvalHashStats(void); - -void -ReportEvalHashStats(void); - -SCORE -ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx); - -SCORE -GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx, - IN SCORE iAlpha, - IN SCORE iBeta, - IN FLAG fUseHash); - -void -StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore); -#endif // EVAL_HASH - -#endif // CHESS diff --git a/src/eval.c b/src/eval.c index a9be77f..2beccbf 100755 --- a/src/eval.c +++ b/src/eval.c @@ -21,7 +21,6 @@ Revision History: #include "chess.h" -typedef void (*PEVAL_HELPER)(POSITION *, COOR, PAWN_HASH_ENTRY *); // // Bishop-mobility ray-walk outcome categories -- see BMobCaseTable in @@ -2412,33 +2411,6 @@ Return value: } -static void -_InvalidEvaluator(UNUSED POSITION *pos, - UNUSED COOR c, - UNUSED PAWN_HASH_ENTRY *pHash) -/** - -Routine description: - - This code should never be called - -Parameters: - - POSITION *pos, - COOR c, - PAWN_HASH_ENTRY *pHash, - -Return value: - - void - -**/ -{ - UtilPanic(SHOULD_NOT_GET_HERE, - NULL, NULL, NULL, NULL, - __FILE__, __LINE__); -} - // // ====================================================================== // @@ -4768,23 +4740,6 @@ Return value: **/ { - static const PEVAL_HELPER JumpTable[] = - { - _InvalidEvaluator, // EMPTY_SQUARE (0) - _InvalidEvaluator, // INVALID_PIECE (1) - _InvalidEvaluator, // BLACK_PAWN (2) - _InvalidEvaluator, // WHITE_PAWN (3) - _EvalKnight, // BLACK_KNIGHT (4) - _EvalKnight, // WHITE_KNIGHT (5) - _EvalBishop, // BLACK_BISHOP (6) - _EvalBishop, // WHITE_BISHOP (7) - _InvalidEvaluator, // BLACK_ROOK (8) - _InvalidEvaluator, // WHITE_ROOK (9) - _InvalidEvaluator, // BLACK_QUEEN (10) - _InvalidEvaluator, // WHITE_QUEEN (11) - _InvalidEvaluator, // BLACK_KING (12) - _InvalidEvaluator // WHITE_KING (13) - }; ULONG uDefer[2][2]; COOR cDefer[2][2][10]; POSITION *pos = &(ctx->sPosition); @@ -5024,12 +4979,17 @@ Return value: // Note: The side on move's pieces of value X are // evaluated and have their mobility counted and added to // the attack table before the other side's pieces. Also, - // we do not care if JumpTable tells us this piece is in - // danger b/c we will find out later on in - // EvalLookForDanger anyway. + // we do not care if this piece is in danger b/c we will + // find out later on in EvalLookForDanger anyway. // - ASSERT(JumpTable[p]); - (void)(JumpTable[p])(pos, c, pHash); + if (IS_KNIGHT(p)) + { + _EvalKnight(pos, c, pHash); + } + else + { + _EvalBishop(pos, c, pHash); + } #ifdef EVAL_DUMP Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), pos->iScore[WHITE], pos->iScore[BLACK]); @@ -5059,13 +5019,18 @@ Return value: // // This time we are evaluating a piece from the side not // on move. We will not go back later and look at this - // piece again so if JumpTable tells us it's in danger - // then record it. The drawback, of course, is that the - // JumpTable routines only detect danger if a piece is - // attacked by an enemy of lesser value! + // piece again so if it's in danger then record it. The + // drawback, of course, is that danger is only detected if + // a piece is attacked by an enemy of lesser value! // - ASSERT(JumpTable[p]); - (void)(JumpTable[p])(pos, c, pHash); + if (IS_KNIGHT(p)) + { + _EvalKnight(pos, c, pHash); + } + else + { + _EvalBishop(pos, c, pHash); + } #ifdef EVAL_DUMP Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), pos->iScore[WHITE], pos->iScore[BLACK]); @@ -5162,7 +5127,6 @@ Return value: ASSERT(IS_VALID_PIECE(p)); ASSERT(GET_COLOR(p) == BLACK); ASSERT(IS_KING(p)); - ASSERT(JumpTable[p]); #endif _EvalKing(pos, c, pHash); ctx->sPlyInfo[ctx->uPly].iKingScore[BLACK] = pos->iTempScore; @@ -5177,7 +5141,6 @@ Return value: ASSERT(IS_VALID_PIECE(p)); ASSERT(GET_COLOR(p) == WHITE); ASSERT(IS_KING(p)); - ASSERT(JumpTable[p]); #endif _EvalKing(pos, c, pHash); ctx->sPlyInfo[ctx->uPly].iKingScore[WHITE] = pos->iTempScore; diff --git a/src/root.c b/src/root.c index d9768fe..7a27ae7 100755 --- a/src/root.c +++ b/src/root.c @@ -978,7 +978,7 @@ _IterateSetSearchGlobals(ULONG uDepth) // Determine how much depth we need below a point in the tree in // order to split the search (which is based on iteration depth). // - uDontSplitLessThan = (ULONG)((double)(uDepth) * 0.30); + uDontSplitLessThan = (ULONG)((double)(uDepth) * 0.20); for (v = 0; v < MAX_PLY_PER_SEARCH; v++) { g_fCanSplit[v] = ((v + 1) >= uDontSplitLessThan); diff --git a/src/search.c b/src/search.c index ab7d122..3879d9f 100755 --- a/src/search.c +++ b/src/search.c @@ -337,7 +337,12 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, } // Maybe do nullmove pruning - iRoughEval = GetRoughEvalScore(ctx, iAlpha, iBeta, FALSE); + pi->iEval = iRoughEval = GetRoughEvalScore(ctx, iAlpha, iBeta, FALSE); + SCORE iImprovement = 0; + if (ctx->uPly > 1) + { + iImprovement = (iRoughEval - ctx->sPlyInfo[ctx->uPly - 2].iEval); + } GENERATE_NO_MOVES; if (!fSkipNull && !fThreat && @@ -345,6 +350,7 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, iAlpha, iBeta, iRoughEval, + iImprovement, uNextDepth)) { if (TryNullmovePruning(ctx, @@ -466,6 +472,7 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, ctx->sSearchFlags.fAvoidNullmove = TRUE; RescoreMovesViaSearch(ctx, uDepth, iAlpha, iBeta); ctx->sSearchFlags.fAvoidNullmove = FALSE; + ASSERT(TRUE == pi->fMovesRescoredByIID); } } #endif @@ -625,12 +632,13 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, // underflow (ULONG) in that case, which is exactly why the // uDepth >= ONE_PLY check below short-circuits before the // g_fCanSplit[] indexing ever evaluates it. - if (((uLegalMoves >= 2)) && + if (((uLegalMoves >= 3)) && (0 != g_uNumHelpersAvailable) && + (FALSE == pi->fMovesRescoredByIID) && (0 == uFutilityMargin) && (uDepth >= ONE_PLY) && (TRUE == g_fCanSplit[uDepth / ONE_PLY - 1]) && - (MOVE_COUNT(ctx, ctx->uPly) > 3)) + (MOVE_COUNT(ctx, ctx->uPly) > 4)) { ASSERT(pf->fAvoidNullmove == FALSE); ASSERT(uStage == TRY_GENERATED_MOVES); diff --git a/src/searchsup.c b/src/searchsup.c index 72667c8..d2cbbbd 100644 --- a/src/searchsup.c +++ b/src/searchsup.c @@ -1089,14 +1089,14 @@ SelectNullmoveRFactor(SEARCHER_THREAD_CONTEXT *ctx, } -FLAG -WeShouldTryNullmovePruning(SEARCHER_THREAD_CONTEXT *ctx, - SCORE iAlpha, - SCORE iBeta, - SCORE iRoughEval, - ULONG uNullDepth) +FLAG WeShouldTryNullmovePruning(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iRoughEval, + SCORE iImprovement, + ULONG uNullDepth) { - static SCORE _iDistAlphaSkipNull[] = { + static SCORE iSkipNullMargins[] = { 700, 950, 1110, 1150, 1190, 1230, 1270, 0 }; POSITION *pos = &ctx->sPosition; @@ -1119,8 +1119,14 @@ WeShouldTryNullmovePruning(SEARCHER_THREAD_CONTEXT *ctx, { u = uNullDepth / ONE_PLY; ASSERT(u <= 6); - if ((iRoughEval + _iDistAlphaSkipNull[u] <= iAlpha) || - ((iRoughEval + _iDistAlphaSkipNull[u] / 2 <= iAlpha) && + SCORE iMargin = iSkipNullMargins[u]; + if (iImprovement > 0) + { + iMargin -= iImprovement; + iMargin = MAX(0, iMargin); + } + if ((iRoughEval + iMargin <= iAlpha) || + ((iRoughEval + iMargin / 2 <= iAlpha) && (ValueOfMaterialInTroubleAfterNull(ctx, pos->uToMove)))) { return FALSE; -- cgit v1.3