Key Position::zobCastle[16];
Key Position::zobMaterial[2][8][16];
Key Position::zobSideToMove;
+Key Position::zobExclusion;
Score Position::PieceSquareTable[16][64];
while (fen[i] == ' ')
i++;
- // En passant square
+ // En passant square -- ignore if no capture is possible
if ( i <= fen.length() - 2
&& (fen[i] >= 'a' && fen[i] <= 'h')
&& (fen[i+1] == '3' || fen[i+1] == '6'))
- st->epSquare = square_from_string(fen.substr(i, 2));
+ {
+ Square fenEpSquare = square_from_string(fen.substr(i, 2));
+ Color them = opposite_color(sideToMove);
+ if (attacks_from<PAWN>(fenEpSquare, them) & this->pieces(PAWN, sideToMove))
+ st->epSquare = square_from_string(fen.substr(i, 2));
+ }
// Various initialisation
for (Square sq = SQ_A1; sq <= SQ_H8; sq++)
fen += (sideToMove == WHITE ? "w " : "b ");
if (st->castleRights != NO_CASTLES)
{
- if (can_castle_kingside(WHITE)) fen += 'K';
- if (can_castle_queenside(WHITE)) fen += 'Q';
- if (can_castle_kingside(BLACK)) fen += 'k';
- if (can_castle_queenside(BLACK)) fen += 'q';
+ if (initialKFile == FILE_E && initialQRFile == FILE_A && initialKRFile == FILE_H)
+ {
+ if (can_castle_kingside(WHITE)) fen += 'K';
+ if (can_castle_queenside(WHITE)) fen += 'Q';
+ if (can_castle_kingside(BLACK)) fen += 'k';
+ if (can_castle_queenside(BLACK)) fen += 'q';
+ }
+ else
+ {
+ if (can_castle_kingside(WHITE))
+ fen += toupper(file_to_char(initialKRFile));
+ if (can_castle_queenside(WHITE))
+ fen += toupper(file_to_char(initialQRFile));
+ if (can_castle_kingside(BLACK))
+ fen += file_to_char(initialKRFile);
+ if (can_castle_queenside(BLACK))
+ fen += file_to_char(initialQRFile);
+ }
} else
fen += '-';
/// king) pieces for the given color and for the given pinner type. Or, when
/// template parameter FindPinned is false, the pieces of the given color
/// candidate for a discovery check against the enemy king.
-/// Note that checkersBB bitboard must be already updated.
+/// Bitboard checkersBB must be already updated when looking for pinners.
template<bool FindPinned>
Bitboard Position::hidden_checkers(Color c) const {
/// Position:pinned_pieces() returns a bitboard of all pinned (against the
-/// king) pieces for the given color.
+/// king) pieces for the given color. Note that checkersBB bitboard must
+/// be already updated.
Bitboard Position::pinned_pieces(Color c) const {
/// Position:discovered_check_candidates() returns a bitboard containing all
/// pieces for the given side which are candidates for giving a discovered
-/// check.
+/// check. Contrary to pinned_pieces() here there is no need of checkersBB
+/// to be already updated.
Bitboard Position::discovered_check_candidates(Color c) const {
Key pawnKey, materialKey;
int castleRights, rule50, pliesFromNull;
Square epSquare;
- Value value;
+ Score value;
Value npMaterial[2];
};
set_bit(&(byColorBB[us]), rto);
set_bit(&(byTypeBB[ROOK]), rto);
set_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares
-
+
// Update board array
Piece king = piece_of_color_and_type(us, KING);
Piece rook = piece_of_color_and_type(us, ROOK);
assert(piece_on(kto) == piece_of_color_and_type(us, KING));
assert(piece_on(rto) == piece_of_color_and_type(us, ROOK));
-
+
// Remove pieces from destination squares:
clear_bit(&(byColorBB[us]), kto);
clear_bit(&(byTypeBB[KING]), kto);
clear_bit(&(byColorBB[us]), rto);
clear_bit(&(byTypeBB[ROOK]), rto);
clear_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares
-
+
// Put pieces on source squares:
set_bit(&(byColorBB[us]), kfrom);
set_bit(&(byTypeBB[KING]), kfrom);
for (int i = 0; i < 16; i++)
zobMaterial[0][KING][i] = zobMaterial[1][KING][i] = Key(0ULL);
+
+ zobExclusion = genrand_int64();
}
static const bool debugNonPawnMaterial = false;
static const bool debugPieceCounts = false;
static const bool debugPieceList = false;
+ static const bool debugCastleSquares = false;
if (failedStep) *failedStep = 1;
return false;
}
}
+
+ if (failedStep) (*failedStep)++;
+ if (debugCastleSquares) {
+ for (Color c = WHITE; c <= BLACK; c++) {
+ if (can_castle_kingside(c) && piece_on(initial_kr_square(c)) != piece_of_color_and_type(c, ROOK))
+ return false;
+ if (can_castle_queenside(c) && piece_on(initial_qr_square(c)) != piece_of_color_and_type(c, ROOK))
+ return false;
+ }
+ if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO))
+ return false;
+ if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO))
+ return false;
+ if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO))
+ return false;
+ if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO))
+ return false;
+ }
+
if (failedStep) *failedStep = 0;
return true;
}