Now we have defined how the occupancy of any rank, file or
diagonal is transformed into a 6-bit address range ( 0..63), and
we can look up the moves in attack bitboards by this type of
construct:
RANK_MOVES = RANK_ATTACKS[from][((board.occupiedSquares
& someMASK[from]) * someMAGIC[from]) >> 57] & targetBitmap;
Actually, we only need 7 macro's to define all lookup's of
sliding moves; (a) is the from-field:
#define RANKMOVES(a) (RANK_ATTACKS[(a)][((board.occupiedSquares
& RANKMASK[(a)]) >> RANKSHIFT[(a)])] & targetBitmap)
#define FILEMOVES(a) (FILE_ATTACKS[(a)][((board.occupiedSquares
& FILEMASK[(a)]) * FILEMAGIC[(a)]) >> 57] & targetBitmap)
#define SLIDEA8H1MOVES(a)
(DIAGA8H1_ATTACKS[(a)][((board.occupiedSquares & DIAGA8H1MASK[(a)]) *
DIAGA8H1MAGIC[(a)]) >> 57] & targetBitmap)
#define SLIDEA1H8MOVES(a)
(DIAGA1H8_ATTACKS[(a)][((board.occupiedSquares & DIAGA1H8MASK[(a)]) *
DIAGA1H8MAGIC[(a)]) >> 57] & targetBitmap)
#define ROOKMOVES(a) (RANKMOVES(a)
| FILEMOVES(a))
#define BISHOPMOVES(a)
(SLIDEA8H1MOVES(a) | SLIDEA1H8MOVES(a))
#define QUEENMOVES(a) (BISHOPMOVES(a)
| ROOKMOVES(a))
The next step is to populate the attack[from][occupancy]-bitboards, at
program startup. To make this somewhat easier, we first initialize
an array GEN_SLIDING_ATTACKS:
unsigned
char
GEN_SLIDING_ATTACKS[8][64];
This arrays contains all possible sliding attack combinations (stored as
unsigned
char, so
8 bits), the first address index is the relative location of the
attacker on the file, rank or diagonal (so
0..8), and the second address index is the occupancy state (0..63).
Example:
GEN_SLIDING_ATTACKS[5][19] = 220, why?
An occupancy of 00100110
translates to an index = 19, because we remove the first and
last bit, ending up with 010011 (decimal
19).
An attacker on bit number 5 (00100000,
counting from right to left, and starting from 0), will have the
following attack bits set:
1101100 (decimal 220).
Hence:
GEN_SLIDING_ATTACKS[5][19] = 220
Using
GEN_SLIDING_ATTACKS[8][64] is a convenient way to populate all
the
RANK_ATTACKS[64][64], FILE_ATTACKS[64][64], DIAGA8H1_ATTACKS[64][64]
and
DIAGA1H8_ATTACKS[64][64] bitboards.
This is done in
void dataInit(),
at program start-up.
That's all there is to bitboard move generation, using magic
multiplication numbers.
This rather lengthy explanation is not covering every little detail, but
it should be
sufficient to understand the code. All relevant code snippets follow
(some are long!):
#ifndef WINGLET_BOARD_H_
#define WINGLET_BOARD_H_
#include
"defines.h"
#include "move.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
void init();
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
#include <iostream>
#include <iomanip>
#include "defines.h"
#include "protos.h"
#include "extglobals.h"
void dataInit()
{
unsigned
char CHARBITSET[8];
int i,
square, rank, file, arank, afile, state, slide, diaga1h8, diaga8h1,
attackbit;
unsigned
char state6Bit, state8Bit,
attack8Bit;
Move move;
//
===========================================================================
// BITSET has only one bit set:
//
===========================================================================
BITSET[0] = 0x1;
for (i = 1; i
< 64 ; i++)
{
BITSET[i] = BITSET[i-1] << 1;
}
//
===========================================================================
// BOARDINDEX is used to translate [file][rank]
to [square],
// Note that file is from 1..8 and rank
from 1..8 (not starting from 0)
//
===========================================================================
for (rank = 0
; rank < 9; rank++)
{
for
(file = 0 ; file < 9; file++)
{
BOARDINDEX[file][rank] =
(rank-1) * 8 + file - 1;
}
}
//
===========================================================================
// Initialize the board
//
===========================================================================
board.init();
//
===========================================================================
// Initialize MS1BTABLE, used in
lastOne (see bitops.cpp)
//
===========================================================================
for (i = 0; i <
256; i++)
{
MS1BTABLE[i] = (
(i > 127) ? 7 :
(i > 63) ? 6 :
(i > 31) ? 5 :
(i > 15) ? 4 :
(i > 7) ? 3 :
(i > 3) ? 2 :
(i > 1) ? 1 : 0 );
}
//
===========================================================================
// Initialize rank, file and
diagonal 6-bit masking bitmaps, to get the
// occupancy state, used in the movegenerator (see movegen.ccp)
//
===========================================================================
for (square =
0; square < 64; square++)
{
RANKMASK[square] = 0x0;
FILEMASK[square] = 0x0;
DIAGA8H1MASK[square] = 0x0;
DIAGA1H8MASK[square] = 0x0;
FILEMAGIC[square] = 0x0;
DIAGA8H1MAGIC[square] = 0x0;
DIAGA1H8MAGIC[square] = 0x0;
}
for (file =
1; file < 9; file++)
{
for
(rank = 1; rank < 9; rank++)
{
//
===========================================================================
// initialize 6-bit rank
mask, used in the movegenerator (see movegen.ccp)
//
===========================================================================
RANKMASK[BOARDINDEX[file][rank]] = BITSET[BOARDINDEX[2][rank]] |
BITSET[BOARDINDEX[3][rank]] | BITSET[BOARDINDEX[4][rank]] ;
RANKMASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[5][rank]] |
BITSET[BOARDINDEX[6][rank]] | BITSET[BOARDINDEX[7][rank]] ;
//
===========================================================================
// initialize 6-bit file
mask, used in the movegenerator (see movegen.ccp)
//
===========================================================================
FILEMASK[BOARDINDEX[file][rank]] = BITSET[BOARDINDEX[file][2]] |
BITSET[BOARDINDEX[file][3]] | BITSET[BOARDINDEX[file][4]] ;
FILEMASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[file][5]] |
BITSET[BOARDINDEX[file][6]] | BITSET[BOARDINDEX[file][7]] ;
//
===========================================================================
// Initialize diagonal magic
multiplication numbers, used in the movegenerator (see movegen.ccp)
//
===========================================================================
diaga8h1 = file + rank;
// from 2 to 16, longest diagonal = 9
DIAGA8H1MAGIC[BOARDINDEX[file][rank]] = _DIAGA8H1MAGICS[diaga8h1 -
2];
//
===========================================================================
// Initialize 6-bit diagonal
mask, used in the movegenerator (see movegen.ccp)
//
===========================================================================
DIAGA8H1MASK[BOARDINDEX[file][rank]] = 0x0;
if
(diaga8h1 < 10) // lower half, diagonals
2 to 9
{
for (square = 2 ; square < diaga8h1-1 ; square ++)
{
DIAGA8H1MASK[BOARDINDEX[file][rank]] |=
BITSET[BOARDINDEX[square][diaga8h1-square]];
}
}
else
// upper half, diagonals 10 to 16
{
for (square = 2 ; square < 17 - diaga8h1 ; square ++)
{
DIAGA8H1MASK[BOARDINDEX[file][rank]] |=
BITSET[BOARDINDEX[diaga8h1+square-9][9-square]];
}
}
//
===========================================================================
// Initialize diagonal magic
multiplication numbers, used in the movegenerator (see movegen.ccp)
//
===========================================================================
diaga1h8 = file - rank;
// from -7 to +7, longest diagonal = 0
DIAGA1H8MAGIC[BOARDINDEX[file][rank]] = _DIAGA1H8MAGICS[diaga1h8+7];
//
===========================================================================
// Initialize 6-bit diagonal
mask, used in the movegenerator (see movegen.ccp)
//
===========================================================================
DIAGA1H8MASK[BOARDINDEX[file][rank]] = 0x0;
if
(diaga1h8 > -1) // lower half, diagonals
0 to 7
{
for (square = 2 ; square < 8 - diaga1h8 ; square ++)
{
DIAGA1H8MASK[BOARDINDEX[file][rank]] |= BITSET[BOARDINDEX[diaga1h8 +
square][square]];
}
}
else
{
for (square = 2 ; square < 8 + diaga1h8 ; square ++)
{
DIAGA1H8MASK[BOARDINDEX[file][rank]] |=
BITSET[BOARDINDEX[square][square - diaga1h8]];
}
}
//
===========================================================================
// Initialize file magic
multiplication numbers, used in the movegenerator (see movegen.ccp)
//
===========================================================================
FILEMAGIC[BOARDINDEX[file][rank]] = _FILEMAGICS[file-1];
}
}
//
===========================================================================
// Now initialize the
GEN_SLIDING_ATTACKS array, used to generate the sliding
// attack bitboards.
// unsigned char GEN_SLIDING_ATTACKS[8
squares][64 states] holds the attacks
// for any file, rank or diagonal - it
is going to be usefull when generating the
// RANK_ATTACKS[64][64],
FILE_ATTACKS[64][64], DIAGA8H1_ATTACKS[64][64] and
// DIAGA1H8_ATTACKS[64][64] arrays
//
===========================================================================
// initialize
CHARBITSET, this array is equivalant to BITSET for bitboards:
// 8 chars, each
with only 1 bit set.
CHARBITSET[0] = 1;
for (square =
1; square <= 7; square++)
{
CHARBITSET[square] =
CHARBITSET[square-1] << 1;
}
// loop over rank,
file or diagonal squares:
for (square =
0; square <= 7; square++)
{
// loop of
occupancy states
// state6Bit
represents the 64 possible occupancy states of a rank,
// except
the 2 end-bits, because they don't matter for calculating attacks
for
(state6Bit = 0; state6Bit < 64; state6Bit++)
{
state8Bit = state6Bit << 1;
// create an 8-bit occupancy state
attack8Bit = 0;
if
(square < 7)
{
attack8Bit |=
CHARBITSET[square + 1];
}
slide = square + 2;
while
(slide <= 7) // slide in '+' direction
{
if ((~state8Bit) & (CHARBITSET[slide - 1]))
{
attack8Bit |=
CHARBITSET[slide];
}
else break;
slide++;
}
if
(square > 0)
{
attack8Bit |=
CHARBITSET[square - 1];
}
slide = square - 2;
while
(slide >= 0) // slide in '-' direction
{
if ((~state8Bit) & (CHARBITSET[slide + 1]))
{
attack8Bit |=
CHARBITSET[slide];
}
else break;
slide--;
}
GEN_SLIDING_ATTACKS[square][state6Bit] = attack8Bit;
}
}
//
===========================================================================
// Initialize all attack bitmaps,
used in the movegenerator (see movegen.ccp)
//
===========================================================================
for (square =
0; square < 64; square++)
{
KNIGHT_ATTACKS[square] = 0x0;
KING_ATTACKS[square] = 0x0;
WHITE_PAWN_ATTACKS[square] = 0x0;
WHITE_PAWN_MOVES[square] = 0x0;
WHITE_PAWN_DOUBLE_MOVES[square] = 0x0;
BLACK_PAWN_ATTACKS[square] = 0x0;
BLACK_PAWN_MOVES[square] = 0x0;
BLACK_PAWN_DOUBLE_MOVES[square] =
0x0;
for
(state = 0; state < 64; state++)
{
RANK_ATTACKS[square][state] =
0x0;
FILE_ATTACKS[square][state] =
0x0;
DIAGA8H1_ATTACKS[square][state]
= 0x0;
DIAGA1H8_ATTACKS[square][state]
= 0x0;
}
}
//
WHITE_PAWN_ATTACKS
for (square =
0; square < 64; square++)
{
file = FILES[square]; rank =
RANKS[square];
afile = file - 1; arank = rank + 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
WHITE_PAWN_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank + 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
WHITE_PAWN_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
}
// WHITE_PAWN_MOVES
for (square =
0; square <64; square++)
{
file = FILES[square]; rank =
RANKS[square];
afile = file; arank = rank + 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
WHITE_PAWN_MOVES[square] |=
BITSET[BOARDINDEX[afile][arank]];
if
(rank == 2)
{
afile = file; arank = rank + 2;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
WHITE_PAWN_DOUBLE_MOVES[square] |= BITSET[BOARDINDEX[afile][arank]];
}
}
//
BLACK_PAWN_ATTACKS
for (square =
0; square < 64; square++)
{
file = FILES[square]; rank =
RANKS[square];
afile = file - 1; arank = rank - 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
BLACK_PAWN_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
BLACK_PAWN_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
}
// BLACK_PAWN_MOVES
for (square =
0; square < 64; square++)
{
file = FILES[square]; rank =
RANKS[square];
afile = file; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
BLACK_PAWN_MOVES[square] |=
BITSET[BOARDINDEX[afile][arank]];
if
(rank == 7)
{
afile = file; arank = rank - 2;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
BLACK_PAWN_DOUBLE_MOVES[square] |= BITSET[BOARDINDEX[afile][arank]];
}
}
// KNIGHT attacks;
for (square =
0; square < 64; square++)
{
file = FILES[square];
rank = RANKS[square];
afile = file - 2; arank = rank + 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file - 1; arank = rank + 2;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank + 2;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 2; arank = rank + 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 2; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank - 2;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file - 1; arank = rank - 2;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file - 2; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KNIGHT_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
}
// KING attacks;
for (square =
0; square < 64; square++)
{
file = FILES[square]; rank =
RANKS[square];
afile = file - 1; arank = rank;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file - 1; arank = rank + 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file; arank = rank + 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank + 1;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank;
if ((afile
>= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file + 1; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
afile = file - 1; arank = rank - 1;
if
((afile >= 1) & (afile <= 8) & (arank >= 1) & (arank <= 8))
KING_ATTACKS[square] |=
BITSET[BOARDINDEX[afile][arank]];
}
// RANK attacks
(ROOKS and QUEENS):
// use
unsigned char GEN_SLIDING_ATTACKS[8 squares] [64 states]
// to initialize
BitMap RANK_ATTACKS [64 squares][64 states]
//
for (square =
0; square < 64; square++)
{
for
(state6Bit = 0; state6Bit < 64; state6Bit++)
{
RANK_ATTACKS[square][state6Bit]
= 0;
RANK_ATTACKS[square][state6Bit]
|=
BitMap(GEN_SLIDING_ATTACKS[FILES[square]-1][state6Bit]) <<
(RANKSHIFT[square] - 1);
}
}
// FILE attacks
(ROOKS and QUEENS):
// use
unsigned char GEN_SLIDING_ATTACKS[8 squares] [64 states]
// to initialize
BitMap FILE_ATTACKS [64 squares][64 states]
//
// Occupancy
transformation is as follows:
//
// occupancy
state bits of the file: occupancy state bits in
GEN_SLIDING_ATTACKS:
//
// . . . . .
. . . MSB LSB MSB
// . . . . .
A . . => A B C D E F .
.
// . . . . .
B . .
// . . . . .
C . .
// . . . . .
D . .
// . . . . .
E . .
// . . . . .
F . .
// LSB . . . . .
. . .
//
// The reverse
transformation is as follows:
//
// attack bits in
GEN_SLIDING_ATTACKS: attack bits in the file:
//
// LSB
MSB . . . . . m . . MSB
// m n o p q
r s t => . . . . . n . .
// . . . . . o
. .
// . . . . . p
. .
// . . . . . q
. .
// . . . . . r
. .
// . . . . . s
. .
// LSB . . . . . t
. .
//
for (square =
0; square < 64; square++)
{
for
(state6Bit = 0; state6Bit < 64; state6Bit++)
{
FILE_ATTACKS[square][state6Bit]
= 0x0;
//
check to see if attackbit'-th bit is set in GEN_SLIDING_ATTACKS,
for this combination of square/occupancy state
for
(attackbit = 0; attackbit < 8; attackbit++)
// from LSB to MSB
{
// conversion from 64 board squares to the 8 corresponding
positions in the GEN_SLIDING_ATTACKS array: "8-RANKS[square]"
if (GEN_SLIDING_ATTACKS[8-RANKS[square]][state6Bit] &
CHARBITSET[attackbit])
{
// the bit is set, so we need to update
FILE_ATTACKS accordingly:
// conversion of square/attackbit to the
corresponding 64 board FILE: FILES[square]
// conversion of square/attackbit to the
corresponding 64 board RANK: 8-attackbit
file =
FILES[square];
rank = 8 -
attackbit;
FILE_ATTACKS[square][state6Bit] |= BITSET[BOARDINDEX[file][rank]];
}
}
}
}
//
DIAGA8H1_ATTACKS attacks (BISHOPS and QUEENS):
for (square =
0; square < 64; square++)
{
for
(state6Bit = 0; state6Bit < 64; state6Bit++)
{
DIAGA8H1_ATTACKS[square][state6Bit] = 0x0;
for
(attackbit = 0; attackbit < 8; attackbit++)
// from LSB to MSB
{
// conversion from 64 board squares to the 8 corresponding
positions in the GEN_SLIDING_ATTACKS array:
MIN((8-RANKS[square]),(FILES[square]-1))
if (GEN_SLIDING_ATTACKS[(8-RANKS[square]) < (FILES[square]-1)
? (8-RANKS[square]) : (FILES[square]-1)][state6Bit] &
CHARBITSET[attackbit])
{
// the bit is set, so we need to update
FILE_ATTACKS accordingly:
// conversion of square/attackbit to the
corresponding 64 board file and rank:
diaga8h1 =
FILES[square] + RANKS[square]; // from 2
to 16, longest diagonal = 9
if (diaga8h1 < 10)
{
file = attackbit
+ 1;
rank = diaga8h1
- file;
}
else
{
rank = 8 -
attackbit;
file = diaga8h1
- rank;
}
if ((file > 0) && (file < 9) &&
(rank > 0) && (rank < 9))
{
DIAGA8H1_ATTACKS[square][state6Bit] |=
BITSET[BOARDINDEX[file][rank]];
}
}
}
}
}
//
DIAGA1H8_ATTACKS attacks (BISHOPS and QUEENS):
for (square =
0; square < 64; square++)
{
for
(state6Bit = 0; state6Bit < 64; state6Bit++)
{
DIAGA1H8_ATTACKS[square][state6Bit] = 0x0;
for
(attackbit = 0; attackbit < 8; attackbit++)
// from LSB to MSB
{
// conversion from 64 board squares to the 8 corresponding
positions in the GEN_SLIDING_ATTACKS array:
MIN((8-RANKS[square]),(FILES[square]-1))
if (GEN_SLIDING_ATTACKS[(RANKS[square]-1) < (FILES[square]-1)
? (RANKS[square]-1) : (FILES[square]-1)][state6Bit] &
CHARBITSET[attackbit])
{
// the bit is set, so we need to update
FILE_ATTACKS accordingly:
// conversion of square/attackbit to the
corresponding 64 board file and rank:
diaga1h8 =
FILES[square] - RANKS[square]; // from -7
to 7, longest diagonal = 0
if (diaga1h8 < 0)
{
file = attackbit
+ 1;
rank = file -
diaga1h8;
}
else
{
rank = attackbit
+ 1;
file = diaga1h8
+ rank;
}
if ((file > 0) && (file < 9) &&
(rank > 0) && (rank < 9))
{
DIAGA1H8_ATTACKS[square][state6Bit] |= BITSET[BOARDINDEX[file][rank]];
}
}
}
}
}
//
===========================================================================
// Masks for castling, index 0 is
for white, 1 is for black
//
===========================================================================
maskEG[0] = BITSET[E1] | BITSET[F1] |
BITSET[G1];
maskEG[1] = BITSET[E8] | BITSET[F8] |
BITSET[G8];
maskFG[0] = BITSET[F1] | BITSET[G1];
maskFG[1] = BITSET[F8] | BITSET[G8];
maskBD[0] = BITSET[B1] | BITSET[C1] |
BITSET[D1];
maskBD[1] = BITSET[B8] | BITSET[C8] |
BITSET[D8];
maskCE[0] = BITSET[C1] | BITSET[D1] |
BITSET[E1];
maskCE[1] = BITSET[C8] | BITSET[D8] |
BITSET[E8];
//
===========================================================================
// The 4 castling moves can be
predefined:
//
===========================================================================
move.clear();
move.setCapt(EMPTY);
move.setPiec(WHITE_KING);
move.setProm(WHITE_KING);
move.setFrom(E1);
move.setTosq(G1);
WHITE_OO_CASTL = move.moveInt;
move.setTosq(C1);
WHITE_OOO_CASTL = move.moveInt;
move.setPiec(BLACK_KING);
move.setProm(BLACK_KING);
move.setFrom(E8);
move.setTosq(G8);
BLACK_OO_CASTL = move.moveInt;
move.setTosq(C8);
BLACK_OOO_CASTL = move.moveInt;
return;
}
void info()
{
// your
playground... display variables - meant for testing/verification
purposes only
std::cout << std::endl <<
"============ info start =============="
<< std::endl;
std::cout <<
"size of board, in bytes = " <<
sizeof(board) << std::endl;
std::cout <<
"Material value = " << board.Material << std::endl;
std::cout <<
"White castling rights = " <<
int(board.castleWhite) << std::endl;
std::cout <<
"Black castling rights = " <<
int(board.castleBlack) << std::endl;
std::cout <<
"En-passant square = " << board.epSquare << std::endl;
std::cout <<
"Fifty move count = " << board.fiftyMove <<
std::endl;
std::cout <<
"============ info end ================" << std::endl <<
std::endl;
return;
}
|