From this point onwards, most improvements are aimed at improving the search algorithm. However, before
we continue doing that, there are some loose ends that need to be
attended. First, we are going to detect if the game has ended due to a
checkmate or draw.
Draws can be due to:
1) insufficient material to mate
1a) king versus king
1b) king + knight versus
king
1c) kings with one or
more bishops, and all bishops on the same color
2) stalemate
3) a threefold repetition of the position (see
section 16)
4) the 50-move rule
All, except the 'threefold repetition', will be implemented now. It
basically means that you can start playing a real game (using the
command 'go'), and the program can also play a game versus itself
(using the 'cc' command). If the game has ended, the program will stop
playing and show the result.
Note that, when using the cc command, you can interrupt the game by
hitting any key.
Checkmate / stalemate detection
Detection of checkmate and stalemate can be done at the end of the
search, after all moves have been tried. If no legal moves were found,
then it must be either checkmate or stalemate (depending on if our own
king is attacked or not), and we return the corresponding score.
The checkmate score is slightly modified so that the program will prefer
the shortest line of play leading to checkmate:
if (!movesfound)
{
if (isOwnKingAttacked())
return (-CHECKMATESCORE+ply-1);
else
return (STALEMATESCORE);
}
50-move rule
The fiftyMove counter is kept up to date
in the board structure, so we just have to add this test at the end of
the search function, after all moves have been tried:
if (fiftyMove >=
100) return DRAWSCORE;
Insufficient material
Insufficient material to checkmate is detected in the evaluation
function.
1a) king versus king
1b) king + knight versus
king
1c) 2 kings with one or
more bishops, and all bishops on the same color
In case any of these three situations exists, the evaluation function
will return a draw score.
Apart from above tests, there is also a function
board::isEndOfgame() that is called before and after
think(), to see if the current position is
an 'end-of-game' position, in which case we don't start the
search and just display the result.
I think it's important to give quality information to the user. This
includes showing current search speed (in knods/s), total number of
nodes visited, total time searched, the currently searched root move, and
last but not least the complete principal variation (in SAN notation). It
just makes the search much easier to follow for chess players. Our algorithm will
also take care of disambiguation. Ambiguity happens if, for example, two rooks (one on a5, one on e1) can move to the same square,
in this case e5. Displaying this move as 'Re5' is not very helpful, because
it's not telling us which rook is moving to e5. Depending on the
location of the other rooks, the move will either be displayed as 'Rae5',
'R1e5',
or 'Ra5e5' (in case there are three rooks that can move to e5). The
SAN
disambiguation rules are followed.
#ifndef WINGLET_GLOBALS_H
#define WINGLET_GLOBALS_H
#include
"defines.h"
#include
"board.h"
char CMD_BUFF[MAX_CMD_BUFF];
int CMD_BUFF_COUNT = 0;
Board board;
extern
const
int
A8 = 56; extern
const
int
B8 = 57; extern
const
int
C8 = 58; extern
const
int
D8 = 59;
extern
const
int
E8 = 60; extern
const
int
F8 = 61; extern
const
int
G8 = 62; extern
const
int
H8 = 63;
extern
const
int
A7 = 48; extern
const
int
B7 = 49; extern
const
int
C7 = 50; extern
const
int
D7 = 51;
extern
const
int
E7 = 52; extern
const
int
F7 = 53; extern
const
int
G7 = 54; extern
const
int
H7 = 55;
extern
const
int
A6 = 40; extern
const
int
B6 = 41; extern
const
int
C6 = 42; extern
const
int
D6 = 43;
extern
const
int
E6 = 44; extern
const
int
F6 = 45; extern
const
int
G6 = 46; extern
const
int
H6 = 47;
extern
const
int
A5 = 32; extern
const
int
B5 = 33; extern
const
int
C5 = 34; extern
const
int
D5 = 35;
extern
const
int
E5 = 36; extern
const
int
F5 = 37; extern
const
int
G5 = 38; extern
const
int
H5 = 39;
extern
const
int
A4 = 24; extern
const
int
B4 = 25; extern
const
int
C4 = 26; extern
const
int
D4 = 27;
extern
const
int
E4 = 28; extern
const
int
F4 = 29; extern
const
int
G4 = 30; extern
const
int
H4 = 31;
extern
const
int
A3 = 16; extern
const
int
B3 = 17; extern
const
int
C3 = 18; extern
const
int
D3 = 19;
extern
const
int
E3 = 20; extern
const
int
F3 = 21; extern
const
int
G3 = 22; extern
const
int
H3 = 23;
extern
const
int
A2 = 8; extern
const
int
B2 = 9; extern
const
int
C2 = 10; extern
const
int
D2 = 11;
extern
const
int
E2 = 12; extern
const
int
F2 = 13; extern
const
int
G2 = 14; extern
const
int
H2 = 15;
extern
const
int
A1 = 0; extern
const
int
B1 = 1; extern
const
int
C1 = 2; extern
const
int
D1 = 3;
extern
const
int
E1 = 4; extern
const
int
F1 = 5; extern
const
int
G1 = 6; extern
const
int
H1 = 7;
const
char*
SQUARENAME[64] = {"a1","b1","c1","d1","e1","f1","g1","h1",
"a2","b2","c2","d2","e2","f2","g2","h2",
"a3","b3","c3","d3","e3","f3","g3","h3",
"a4","b4","c4","d4","e4","f4","g4","h4",
"a5","b5","c5","d5","e5","f5","g5","h5",
"a6","b6","c6","d6","e6","f6","g6","h6",
"a7","b7","c7","d7","e7","f7","g7","h7",
"a8","b8","c8","d8","e8","f8","g8","h8"};
extern
const
int
FILES[64] = {
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8
};
extern
const
int
RANKS[64] = {
1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8
};
// Identifier of next move:
extern
const
unsigned
char
WHITE_MOVE = 0;
extern
const
unsigned
char
BLACK_MOVE = 1;
// Piece identifiers, 4 bits each.
// Usefull bitwise properties of this numbering scheme:
// white = 0..., black = 1..., sliding = .1.., nonsliding = .0..
// rank/file sliding pieces = .11., diagonally sliding pieces = .1.1
// pawns and kings (without color bits), are < 3
// major pieces (without color bits set), are > 5
// minor and major pieces (without color bits set), are > 2
extern
const
unsigned
char
EMPTY = 0; //
0000
extern
const
unsigned
char
WHITE_PAWN = 1; //
0001
extern
const
unsigned
char
WHITE_KING = 2; //
0010
extern
const
unsigned
char
WHITE_KNIGHT = 3; //
0011
extern
const
unsigned
char
WHITE_BISHOP = 5; //
0101
extern
const
unsigned
char
WHITE_ROOK = 6; //
0110
extern
const
unsigned
char
WHITE_QUEEN = 7; //
0111
extern
const
unsigned
char
BLACK_PAWN = 9; //
1001
extern
const
unsigned
char
BLACK_KING = 10; //
1010
extern
const
unsigned
char
BLACK_KNIGHT = 11; //
1011
extern
const
unsigned
char
BLACK_BISHOP = 13; //
1101
extern
const
unsigned
char
BLACK_ROOK = 14; //
1110
extern
const
unsigned
char
BLACK_QUEEN = 15; //
1111
const
char*
PIECENAMES[16] = {" ","P
","K
","N
","
","B
","R
","Q
",
" ","P*","K*","N*","
","B*","R*","Q*"};
const
char*
PIECECHARS[16] = {" ","
","K","N","
","B","R","Q","
","
","K","N","
","B","R","Q"};
BitMap BITSET[64];
int BOARDINDEX[9][9];
// index 0 is not used, only 1..8.
// Value of material, in centipawns:
extern
const
int
PAWN_VALUE = 100;
extern
const
int
KNIGHT_VALUE = 300;
extern
const
int
BISHOP_VALUE = 300;
extern
const
int
ROOK_VALUE = 500;
extern
const
int
QUEEN_VALUE = 900;
extern
const
int
KING_VALUE = 9999;
extern
const
int
CHECK_MATE = KING_VALUE;
// used in Eugene Nalimov's bitScanReverse
int MS1BTABLE[256];
// Attack tables:
BitMap WHITE_PAWN_ATTACKS[64];
BitMap WHITE_PAWN_MOVES[64];
BitMap WHITE_PAWN_DOUBLE_MOVES[64];
BitMap BLACK_PAWN_ATTACKS[64];
BitMap BLACK_PAWN_MOVES[64];
BitMap BLACK_PAWN_DOUBLE_MOVES[64];
BitMap KNIGHT_ATTACKS[64];
BitMap KING_ATTACKS[64];
BitMap
RANK_ATTACKS[64][64]; //
32KB
BitMap
FILE_ATTACKS[64][64]; //
32KB
BitMap
DIAGA8H1_ATTACKS[64][64]; //
32KB
BitMap
DIAGA1H8_ATTACKS[64][64]; //
32KB
// Move generator shift for ranks:
extern
const
int
RANKSHIFT[64] = {
1, 1, 1, 1, 1, 1, 1, 1,
9, 9, 9, 9, 9, 9, 9, 9,
17, 17, 17, 17, 17, 17, 17, 17,
25, 25, 25, 25, 25, 25, 25, 25,
33, 33, 33, 33, 33, 33, 33, 33,
41, 41, 41, 41, 41, 41, 41, 41,
49, 49, 49, 49, 49, 49, 49, 49,
57, 57, 57, 57, 57, 57, 57, 57
};
// Move generator magic multiplication numbers for files:
extern
const
BitMap _FILEMAGICS[8] = {
0x8040201008040200,
0x4020100804020100,
0x2010080402010080,
0x1008040201008040,
0x0804020100804020,
0x0402010080402010,
0x0201008040201008,
0x0100804020100804
};
// Move generator magic multiplication numbers for diagonals:
extern
const
BitMap _DIAGA8H1MAGICS[15] = {
0x0,
0x0,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0080808080808080,
0x0040404040404040,
0x0020202020202020,
0x0010101010101010,
0x0008080808080808,
0x0,
0x0
};
// Move generator magic multiplication numbers for diagonals:
extern
const
BitMap _DIAGA1H8MAGICS[15] = {
0x0,
0x0,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x0101010101010100,
0x8080808080808000,
0x4040404040400000,
0x2020202020000000,
0x1010101000000000,
0x0808080000000000,
0x0,
0x0
};
// Move generator 6-bit masking and magic multiplication numbers:
BitMap RANKMASK[64];
BitMap FILEMASK[64];
BitMap FILEMAGIC[64];
BitMap DIAGA8H1MASK[64];
BitMap DIAGA8H1MAGIC[64];
BitMap DIAGA1H8MASK[64];
BitMap DIAGA1H8MAGIC[64];
// We use one generalized sliding attacks array: [8 squares][64
states]
// the unsigned char (=8 bits) contains the attacks for a rank, file
or diagonal
unsigned
char
GEN_SLIDING_ATTACKS[8][64];
// Used for castling:
unsigned
char
CANCASTLEOO = 1;
unsigned
char
CANCASTLEOOO = 2;
BitMap maskEG[2];
BitMap maskFG[2];
BitMap maskBD[2];
BitMap maskCE[2];
unsigned
int
WHITE_OOO_CASTL;
unsigned
int
BLACK_OOO_CASTL;
unsigned
int
WHITE_OO_CASTL;
unsigned
int
BLACK_OO_CASTL;
int ICAPT;
int IEP;
int IPROM;
int ICASTLOO;
int ICASTLOOO;
int ICHECK;
// Evaluation scores start here, all scores are in centipawns.
// If there are scoring data that is supposed to be symmetrical
(i.e. same for BLACK & WHITE),
// then only the data for WHITE is supplied, and data for BLACK is
calculated in dataInit().
// This is done to make data entry easier, eliminate typos and
guarantuee symmetry.
//
// MIRRORED:
// Some scoring arrays are supplied MIRRORED, i.e. starting with the
last rank (see the comments below).
// They are mirrored back in the right order in dataInit().
// This is only done to make data entry easier, because you can
enter the scoring data as if you're
// looking at the chess board from White's point of perspective.
int PENALTY_DOUBLED_PAWN = 10;
int PENALTY_ISOLATED_PAWN = 20;
int PENALTY_BACKWARD_PAWN = 8;
int BONUS_PASSED_PAWN = 20;
int BONUS_BISHOP_PAIR = 10;
int BONUS_ROOK_BEHIND_PASSED_PAWN = 20;
int BONUS_ROOK_ON_OPEN_FILE = 20;
int BONUS_TWO_ROOKS_ON_OPEN_FILE = 20;
int BONUS_PAWN_SHIELD_STRONG = 9;
int BONUS_PAWN_SHIELD_WEAK = 4;
int PAWN_OWN_DISTANCE[8] = { 0, 8, 4, 2, 0,
0, 0, 0 };
int PAWN_OPPONENT_DISTANCE[8] = { 0, 2, 1, 0, 0,
0, 0, 0 };
int KNIGHT_DISTANCE[8] = { 0, 4, 4, 0, 0,
0, 0, 0 };
int BISHOP_DISTANCE[8] = { 0, 5, 4, 3, 2,
1, 0, 0 };
int ROOK_DISTANCE[8] = { 0, 7, 5, 4, 3,
0, 0, 0 };
int QUEEN_DISTANCE[8] = { 0, 10, 8, 5, 4,
0, 0, 0 };
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int PAWNPOS_W[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
5, 10, 15, 20, 20, 15, 10, 5,
4, 8, 12, 16, 16, 12, 8, 4,
3, 6, 9, 12, 12, 9, 6, 3,
2, 4, 6, 8, 8, 6, 4, 2,
1, 2, 3, -10, -10, 3, 2, 1,
0, 0, 0, -40, -40, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int KNIGHTPOS_W[64] = {
-10, -10, -10, -10, -10, -10, -10, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, -30, -10, -10, -10, -10, -30, -10
};
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int BISHOPPOS_W[64] = {
-10, -10, -10, -10, -10, -10, -10, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, -10, -20, -10, -10, -20, -10, -10
};
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int ROOKPOS_W[64] = {
0, 0, 0, 0, 0, 0, 0, 0,
15, 15, 15, 15, 15, 15, 15, 15,
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, 0, 0, 0, 0, 0, 0,
-10, 0, 0, 10, 10, 0, 0, -10
};
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int QUEENPOS_W[64] = {
-10, -10, -10, -10, -10, -10, -10, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, -10, -20, -10, -10, -20, -10, -10
};
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int KINGPOS_W[64] = {
-40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40, -40,
-40, -40, -40, -40, -40, -40, -40, -40,
-20, -20, -20, -20, -20, -20, -20, -20,
0, 20, 40, -20, 0, -20, 40, 20
};
// *** This array is MIRRORED ***
// *** You can enter the scoring data as if you're ***
// *** looking at the chess board from white's point ***
// *** of perspective. Lower left corner is square a1: ***
int KINGPOS_ENDGAME_W[64] = {
0, 10, 20, 30, 30, 20, 10, 0,
10, 20, 30, 40, 40, 30, 20, 10,
20, 30, 40, 50, 50, 40, 30, 20,
30, 40, 50, 60, 60, 50, 40, 30,
30, 40, 50, 60, 60, 50, 40, 30,
20, 30, 40, 50, 50, 40, 30, 20,
10, 20, 30, 40, 40, 30, 20, 10,
0, 10, 20, 30, 30, 20, 10, 0
};
int MIRROR[64] = {
56, 57, 58, 59, 60, 61, 62, 63,
48, 49, 50, 51, 52, 53, 54, 55,
40, 41, 42, 43, 44, 45, 46, 47,
32, 33, 34, 35, 36, 37, 38, 39,
24, 25, 26, 27, 28, 29, 30, 31,
16, 17, 18, 19, 20, 21, 22, 23,
8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7
};
int DISTANCE[64][64];
int PAWNPOS_B[64];
int KNIGHTPOS_B[64];
int BISHOPPOS_B[64];
int ROOKPOS_B[64];
int QUEENPOS_B[64];
int KINGPOS_B[64];
int KINGPOS_ENDGAME_B[64];
BitMap PASSED_WHITE[64];
BitMap PASSED_BLACK[64];
BitMap ISOLATED_WHITE[64];
BitMap ISOLATED_BLACK[64];
BitMap BACKWARD_WHITE[64];
BitMap BACKWARD_BLACK[64];
BitMap KINGSHIELD_STRONG_W[64];
BitMap KINGSHIELD_STRONG_B[64];
BitMap KINGSHIELD_WEAK_W[64];
BitMap KINGSHIELD_WEAK_B[64];
BitMap WHITE_SQUARES;
BitMap BLACK_SQUARES;
// Search parameters start here:
int LARGE_NUMBER = KING_VALUE + 1;
int CHECKMATESCORE = KING_VALUE;
int STALEMATESCORE = 0;
int DRAWSCORE = 0;
Move NOMOVE;
#endif
#ifndef WINGLET_EXTGLOBALS_H
#define WINGLET_EXTGLOBALS_H
#include
"defines.h"
#include
"board.h"
extern
char
CMD_BUFF[];
extern
int
CMD_BUFF_COUNT;
extern Board board;
extern
const
int
A8; extern
const
int
B8; extern
const
int
C8; extern
const
int
D8;
extern
const
int
E8; extern
const
int
F8; extern
const
int
G8; extern
const
int
H8;
extern
const
int
A7; extern
const
int
B7; extern
const
int
C7; extern
const
int
D7;
extern
const
int
E7; extern
const
int
F7; extern
const
int
G7; extern
const
int
H7;
extern
const
int
A6; extern
const
int
B6; extern
const
int
C6; extern
const
int
D6;
extern
const
int
E6; extern
const
int
F6; extern
const
int
G6; extern
const
int
H6;
extern
const
int
A5; extern
const
int
B5; extern
const
int
C5; extern
const
int
D5;
extern
const
int
E5; extern
const
int
F5; extern
const
int
G5; extern
const
int
H5;
extern
const
int
A4; extern
const
int
B4; extern
const
int
C4; extern
const
int
D4;
extern
const
int
E4; extern
const
int
F4; extern
const
int
G4; extern
const
int
H4;
extern
const
int
A3; extern
const
int
B3; extern
const
int
C3; extern
const
int
D3;
extern
const
int
E3; extern
const
int
F3; extern
const
int
G3; extern
const
int
H3;
extern
const
int
A2; extern
const
int
B2; extern
const
int
C2; extern
const
int
D2;
extern
const
int
E2; extern
const
int
F2; extern
const
int
G2; extern
const
int
H2;
extern
const
int
A1; extern
const
int
B1; extern
const
int
C1; extern
const
int
D1;
extern
const
int
E1; extern
const
int
F1; extern
const
int
G1; extern
const
int
H1;
extern
const
char*
SQUARENAME[];
extern
const
int
FILES[];
extern
const
int
RANKS[];
extern
const
unsigned
char
WHITE_MOVE;
extern
const
unsigned
char
BLACK_MOVE;
extern
const
unsigned
char
EMPTY;
extern
const
unsigned
char
WHITE_KNIGHT;
extern
const
unsigned
char
WHITE_PAWN;
extern
const
unsigned
char
WHITE_KING;
extern
const
unsigned
char
WHITE_BISHOP;
extern
const
unsigned
char
WHITE_ROOK;
extern
const
unsigned
char
WHITE_QUEEN;
extern
const
unsigned
char
BLACK_KNIGHT;
extern
const
unsigned
char
BLACK_PAWN;
extern
const
unsigned
char
BLACK_KING;
extern
const
unsigned
char
BLACK_BISHOP;
extern
const
unsigned
char
BLACK_ROOK;
extern
const
unsigned
char
BLACK_QUEEN;
extern
const
char*
PIECENAMES[];
extern
const
char*
PIECECHARS[];
extern BitMap BITSET[];
extern
int
BOARDINDEX[9][9];
extern
const
int
PAWN_VALUE;
extern
const
int
KNIGHT_VALUE;
extern
const
int
BISHOP_VALUE;
extern
const
int
ROOK_VALUE;
extern
const
int
QUEEN_VALUE;
extern
const
int
KING_VALUE;
extern
const
int
CHECK_MATE;
extern
int
MS1BTABLE[];
extern BitMap WHITE_PAWN_ATTACKS[];
extern BitMap WHITE_PAWN_MOVES[];
extern BitMap WHITE_PAWN_DOUBLE_MOVES[];
extern BitMap BLACK_PAWN_ATTACKS[];
extern BitMap BLACK_PAWN_MOVES[];
extern BitMap BLACK_PAWN_DOUBLE_MOVES[];
extern BitMap KNIGHT_ATTACKS[];
extern BitMap KING_ATTACKS[];
extern BitMap RANK_ATTACKS[64][64];
extern BitMap FILE_ATTACKS[64][64];
extern BitMap DIAGA8H1_ATTACKS[64][64];
extern BitMap DIAGA1H8_ATTACKS[64][64];
extern
const
int
RANKSHIFT[];
extern
const
BitMap _FILEMAGICS[];
extern
const
BitMap _DIAGA8H1MAGICS[];
extern
const
BitMap _DIAGA1H8MAGICS[];
extern BitMap RANKMASK[];
extern BitMap FILEMAGIC[];
extern BitMap FILEMASK[];
extern BitMap DIAGA8H1MASK[];
extern BitMap DIAGA8H1MAGIC[];
extern BitMap DIAGA1H8MASK[];
extern BitMap DIAGA1H8MAGIC[];
extern
unsigned
char
GEN_SLIDING_ATTACKS[8][64];
extern
unsigned
char
CANCASTLEOO;
extern
unsigned
char
CANCASTLEOOO;
extern BitMap maskEG[];
extern BitMap maskFG[];
extern BitMap maskBD[];
extern BitMap maskCE[];
extern
unsigned
int
WHITE_OOO_CASTL;
extern
unsigned
int
BLACK_OOO_CASTL;
extern
unsigned
int
WHITE_OO_CASTL;
extern
unsigned
int
BLACK_OO_CASTL;
extern
int ICAPT;
extern
int IEP;
extern
int IPROM;
extern
int
ICASTLOO;
extern
int
ICASTLOOO;
extern
int ICHECK;
extern
int
PENALTY_DOUBLED_PAWN;
extern
int
PENALTY_ISOLATED_PAWN;
extern
int
PENALTY_BACKWARD_PAWN;
extern
int
BONUS_PASSED_PAWN;
extern
int
BONUS_BISHOP_PAIR;
extern
int
BONUS_ROOK_BEHIND_PASSED_PAWN;
extern
int
BONUS_ROOK_ON_OPEN_FILE;
extern
int
BONUS_PAWN_SHIELD_STRONG;
extern
int
BONUS_PAWN_SHIELD_WEAK;
extern
int
PAWN_OWN_DISTANCE[];
extern
int
PAWN_OPPONENT_DISTANCE[];
extern
int
KNIGHT_DISTANCE[];
extern
int
BISHOP_DISTANCE[];
extern
int
ROOK_DISTANCE[];
extern
int
QUEEN_DISTANCE[];
extern
int
PAWNPOS_W[];
extern
int
KNIGHTPOS_W[];
extern
int
BISHOPPOS_W[];
extern
int
ROOKPOS_W[];
extern
int
QUEENPOS_W[];
extern
int
KINGPOS_W[];
extern
int
KINGPOS_ENDGAME_W[];
extern
int
MIRROR[];
extern
int
DISTANCE[64][64];
extern
int
PAWNPOS_B[];
extern
int
KNIGHTPOS_B[];
extern
int
BISHOPPOS_B[];
extern
int
ROOKPOS_B[];
extern
int
QUEENPOS_B[];
extern
int
KINGPOS_B[];
extern
int
KINGPOS_ENDGAME_B[];
extern BitMap PASSED_WHITE[];
extern BitMap PASSED_BLACK[];
extern BitMap ISOLATED_WHITE[];
extern BitMap ISOLATED_BLACK[];
extern BitMap BACKWARD_WHITE[];
extern BitMap BACKWARD_BLACK[];
extern BitMap KINGSHIELD_STRONG_W[];
extern BitMap KINGSHIELD_STRONG_B[];
extern BitMap KINGSHIELD_WEAK_W[];
extern BitMap KINGSHIELD_WEAK_B[];
extern BitMap WHITE_SQUARES;
extern BitMap BLACK_SQUARES;
extern int LARGE_NUMBER;
extern int CHECKMATESCORE;
extern int STALEMATESCORE;
extern int DRAWSCORE;
extern Move NOMOVE;
#endif
#ifndef WINGLET_PROTOS_H
#define WINGLET_PROTOS_H
#include
"board.h"
#include
"move.h"
unsigned
int
bitCnt(BitMap);
void dataInit();
void displayBitmap(BitMap);
void displayMove(Move &);
void displayPV();
BOOLTYPE doCommand(const
char
*);
unsigned
int
firstOne(BitMap);
void info();
BOOLTYPE
isAttacked(BitMap &, const
unsigned
char
&);
BOOLTYPE isOtherKingAttacked();
BOOLTYPE isOwnKingAttacked();
BOOLTYPE isValidTextMove(char
*, Move &);
unsigned
int
lastOne(BitMap);
void makeBlackPromotion(unsigned
int,
unsigned
int
&);
void makeCapture(unsigned
int
&, unsigned
int
&);
void makeMove(Move &);
void makeWhitePromotion(unsigned
int,
unsigned
int
&);
int movegen(int);
U64 perft(int,
int);
void readCommands();
BOOLTYPE readFen(char
*, int);
void setup();
void setupFen(char
*, char
*, char
*, char
*, int
, int
);
BOOLTYPE toSan(Move &,
char *);
void unmakeBlackPromotion(unsigned
int,
unsigned
int
&);
void unmakeCapture(unsigned
int
&, unsigned
int
&);
void unmakeMove(Move &);
void unmakeWhitePromotion(unsigned
int,
unsigned
int
&);
#endif
#ifndef WINGLET_BOARD_H_
#define WINGLET_BOARD_H_
#include
"defines.h"
#include
"move.h"
#include
"gameline.h"
#include
"timer.h"
struct Board
{
BitMap whiteKing, whiteQueens, whiteRooks,
whiteBishops, whiteKnights, whitePawns;
BitMap blackKing, blackQueens, blackRooks,
blackBishops, blackKnights, blackPawns;
BitMap whitePieces, blackPieces,
occupiedSquares;
unsigned
char
nextMove; // WHITE_MOVE
or BLACK_MOVE
unsigned
char
castleWhite; // White's
castle status, CANCASTLEOO = 1, CANCASTLEOOO = 2
unsigned
char
castleBlack; // Black's
castle status, CANCASTLEOO = 1, CANCASTLEOOO = 2
int
epSquare; //
En-passant target square after double pawn move
int
fiftyMove; //
Moves since the last pawn move or capture
// additional variables:
int
Material; //
incrementally updated, total material on board,
// in centipawns, from white’s side of
view
int
square[64]; //
incrementally updated, this array is usefull if we want to
// probe what kind of piece is on a
particular square.
BOOLTYPE viewRotated;
// only used for displaying the
board. TRUE or FALSE.
// storing moves:
Move
moveBuffer[MAX_MOV_BUFF]; // all
generated moves of the current search tree are stored in this array.
int
moveBufLen[MAX_PLY]; //
this arrays keeps track of which moves belong to which ply
int
endOfGame; //
index for board.gameLine
int
endOfSearch; //
index for board.gameLine
GameLineRecord gameLine[MAX_GAME_LINE];
// search variables:
int
triangularLength[MAX_PLY];
Move triangularArray[MAX_PLY][MAX_PLY];
Timer timer;
U64 msStart, msStop;
int
searchDepth;
U64 inodes;
void
init();
int eval();
Move think();
int
minimax(int
ply, int
depth);
int
alphabeta(int
ply, int
depth, int
alpha, int
beta);
int
alphabetapvs(int
ply, int
depth, int
alpha, int
beta);
void
displaySearchStats(int
mode, int
depth, int
score);
BOOLTYPE isEndOfgame(int
&legalmoves, Move &singlemove);
void
mirror();
void
initFromSquares(int
input[64], unsigned
char
next, int
fiftyM, int
castleW, int
castleB, int
epSq);
void
initFromFen(char
fen[], char
fencolor[], char
fencastling[], char
fenenpassant[], int
fenhalfmoveclock, int
fenfullmovenumber);
void
display();
};
#endif
|