CheckInfo::CheckInfo(const Position& pos) {
Color them = flip(pos.side_to_move());
- Square ksq = pos.king_square(them);
+ ksq = pos.king_square(them);
pinned = pos.pinned_pieces();
dcCandidates = pos.discovered_check_candidates();
// 1. Piece placement
while ((fen >> token) && !isspace(token))
{
- if (token == '/')
- sq -= Square(16); // Jump back of 2 rows
+ if (isdigit(token))
+ sq += Square(token - '0'); // Advance the given number of files
- else if (isdigit(token))
- sq += Square(token - '0'); // Skip the given number of files
+ else if (token == '/')
+ sq = make_square(FILE_A, rank_of(sq) - Rank(2));
else if ((p = PieceToChar.find(token)) != string::npos)
{
{
Square rsq;
Color c = islower(token) ? BLACK : WHITE;
- Piece rook = make_piece(c, ROOK);
token = char(toupper(token));
if (token == 'K')
- for (rsq = relative_square(c, SQ_H1); piece_on(rsq) != rook; rsq--) {}
+ for (rsq = relative_square(c, SQ_H1); type_of(piece_on(rsq)) != ROOK; rsq--) {}
else if (token == 'Q')
- for (rsq = relative_square(c, SQ_A1); piece_on(rsq) != rook; rsq++) {}
+ for (rsq = relative_square(c, SQ_A1); type_of(piece_on(rsq)) != ROOK; rsq++) {}
else if (token >= 'A' && token <= 'H')
rsq = make_square(File(token - 'A'), relative_rank(c, RANK_1));
else
continue;
- set_castle_right(king_square(c), rsq);
+ set_castle_right(c, rsq);
}
// 4. En passant square. Ignore if no pawn capture is possible
/// Position::set_castle_right() is an helper function used to set castling
-/// rights given the corresponding king and rook starting squares.
+/// rights given the corresponding color and the rook starting square.
-void Position::set_castle_right(Square ksq, Square rsq) {
+void Position::set_castle_right(Color c, Square rsq) {
- int f = (rsq < ksq ? WHITE_OOO : WHITE_OO) << color_of(piece_on(ksq));
+ int f = (rsq < king_square(c) ? WHITE_OOO : WHITE_OO) << c;
st->castleRights |= f;
- castleRightsMask[ksq] ^= f;
+ castleRightsMask[king_square(c)] ^= f;
castleRightsMask[rsq] ^= f;
castleRookSquare[f] = rsq;
}
Square ksq = king_square(FindPinned ? sideToMove : flip(sideToMove));
// Pinners are sliders, that give check when candidate pinned is removed
- pinners &= (pieces(ROOK, QUEEN) & RookPseudoAttacks[ksq])
- | (pieces(BISHOP, QUEEN) & BishopPseudoAttacks[ksq]);
+ pinners &= (pieces(ROOK, QUEEN) & PseudoAttacks[ROOK][ksq])
+ | (pieces(BISHOP, QUEEN) & PseudoAttacks[BISHOP][ksq]);
while (pinners)
{
assert(square_is_ok(s));
Bitboard occ, xray;
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece piece = piece_on(from);
assert(!square_is_empty(from));
assert(pinned == pinned_pieces());
Color us = side_to_move();
- Square from = move_from(m);
+ Square from = from_sq(m);
assert(color_of(piece_on(from)) == us);
assert(piece_on(king_square(us)) == make_piece(us, KING));
if (is_enpassant(m))
{
Color them = flip(us);
- Square to = move_to(m);
+ Square to = to_sq(m);
Square capsq = to + pawn_push(them);
Square ksq = king_square(us);
Bitboard b = occupied_squares();
// square is attacked by the opponent. Castling moves are checked
// for legality during move generation.
if (type_of(piece_on(from)) == KING)
- return is_castle(m) || !(attackers_to(move_to(m)) & pieces(flip(us)));
+ return is_castle(m) || !(attackers_to(to_sq(m)) & pieces(flip(us)));
// A non-king move is legal if and only if it is not pinned or it
// is moving along the ray towards or away from the king.
return !pinned
|| !bit_is_set(pinned, from)
- || squares_aligned(from, move_to(m), king_square(us));
+ || squares_aligned(from, to_sq(m), king_square(us));
}
Color us = sideToMove;
Color them = flip(sideToMove);
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece pc = piece_on(from);
// Use a slower but simpler function for uncommon cases
{
Bitboard b = occupied_squares();
clear_bit(&b, from);
- if (attackers_to(move_to(m), b) & pieces(flip(us)))
+ if (attackers_to(to_sq(m), b) & pieces(flip(us)))
return false;
}
else
// Our move must be a blocking evasion or a capture of the checking piece
target = squares_between(checksq, king_square(us)) | checkers();
- if (!bit_is_set(target, move_to(m)))
+ if (!bit_is_set(target, to_sq(m)))
return false;
}
}
assert(is_ok(m));
assert(ci.dcCandidates == discovered_check_candidates());
- assert(color_of(piece_on(move_from(m))) == side_to_move());
+ assert(color_of(piece_moved(m)) == side_to_move());
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
PieceType pt = type_of(piece_on(from));
// Direct check ?
Color us = side_to_move();
Color them = flip(us);
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece piece = piece_on(from);
PieceType pt = type_of(piece);
PieceType capture = is_enpassant(m) ? PAWN : type_of(piece_on(to));
Color us = side_to_move();
Color them = flip(us);
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
Piece piece = piece_on(to);
PieceType pt = type_of(piece);
PieceType capture = st->capturedType;
Square kto, kfrom, rfrom, rto, kAfter, rAfter;
Color us = side_to_move();
- Square kBefore = move_from(m);
- Square rBefore = move_to(m);
+ Square kBefore = from_sq(m);
+ Square rBefore = to_sq(m);
// Find after-castle squares for king and rook
if (rBefore > kBefore) // O-O
assert(is_ok(m));
- Square from = move_from(m);
- Square to = move_to(m);
+ Square from = from_sq(m);
+ Square to = to_sq(m);
// Early return if SEE cannot be negative because captured piece value
// is not less then capturing one. Note that king moves always return
if (is_castle(m))
return 0;
- from = move_from(m);
- to = move_to(m);
+ from = from_sq(m);
+ to = to_sq(m);
capturedType = type_of(piece_on(to));
occ = occupied_squares();
return true;
// Draw by the 50 moves rule?
- if (st->rule50 > 99 && !is_mate())
+ if (st->rule50 > 99 && (!in_check() || MoveList<MV_LEGAL>(*this).size()))
return true;
// Draw by repetition?
template bool Position::is_draw<true>() const;
-/// Position::is_mate() returns true or false depending on whether the
-/// side to move is checkmated.
-
-bool Position::is_mate() const {
-
- return in_check() && !MoveList<MV_LEGAL>(*this).size();
-}
-
-
/// Position::init() is a static member function which initializes at startup
/// the various arrays used to compute hash keys and the piece square tables.
/// The latter is a two-step operation: First, the white halves of the tables
// Castling rights
if (pos.can_castle(WHITE_OO))
- set_castle_right(king_square(BLACK), flip(pos.castle_rook_square(WHITE_OO)));
+ set_castle_right(BLACK, flip(pos.castle_rook_square(WHITE_OO)));
if (pos.can_castle(WHITE_OOO))
- set_castle_right(king_square(BLACK), flip(pos.castle_rook_square(WHITE_OOO)));
+ set_castle_right(BLACK, flip(pos.castle_rook_square(WHITE_OOO)));
if (pos.can_castle(BLACK_OO))
- set_castle_right(king_square(WHITE), flip(pos.castle_rook_square(BLACK_OO)));
+ set_castle_right(WHITE, flip(pos.castle_rook_square(BLACK_OO)));
if (pos.can_castle(BLACK_OOO))
- set_castle_right(king_square(WHITE), flip(pos.castle_rook_square(BLACK_OOO)));
+ set_castle_right(WHITE, flip(pos.castle_rook_square(BLACK_OOO)));
// En passant square
if (pos.st->epSquare != SQ_NONE)