Bitboard target;
if (Type == MV_CAPTURE || Type == MV_NON_EVASION)
- target = pos.pieces_of_color(opposite_color(us));
+ target = pos.pieces(opposite_color(us));
else if (Type == MV_NON_CAPTURE)
target = pos.empty_squares();
else
mlist = generate_piece_moves<QUEEN>(pos, mlist, us, target);
mlist = generate_piece_moves<KING>(pos, mlist, us, target);
- if (Type != MV_CAPTURE)
+ if (Type != MV_CAPTURE && pos.can_castle(us))
{
- if (pos.can_castle_kingside(us))
+ if (pos.can_castle(us == WHITE ? WHITE_OO : BLACK_OO))
mlist = generate_castle_moves<KING_SIDE>(pos, mlist, us);
- if (pos.can_castle_queenside(us))
+ if (pos.can_castle(us == WHITE ? WHITE_OOO : BLACK_OOO))
mlist = generate_castle_moves<QUEEN_SIDE>(pos, mlist, us);
}
while (b)
{
from = pop_1st_bit(&b);
- switch (pos.type_of_piece_on(from))
+ switch (piece_type(pos.piece_on(from)))
{
case PAWN: /* Will be generated togheter with pawns direct checks */ break;
case KNIGHT: mlist = generate_discovered_checks<KNIGHT>(pos, mlist, from); break;
checkersCnt++;
checksq = pop_1st_bit(&b);
- assert(pos.color_of_piece_on(checksq) == opposite_color(us));
+ assert(piece_color(pos.piece_on(checksq)) == opposite_color(us));
- switch (pos.type_of_piece_on(checksq))
+ switch (piece_type(pos.piece_on(checksq)))
{
case BISHOP: sliderAttacks |= BishopPseudoAttacks[checksq]; break;
case ROOK: sliderAttacks |= RookPseudoAttacks[checksq]; break;
case QUEEN:
- // In case of a queen remove also squares attacked in the other direction to
- // avoid possible illegal moves when queen and king are on adjacent squares.
- if (RookPseudoAttacks[checksq] & (1ULL << ksq))
- sliderAttacks |= RookPseudoAttacks[checksq] | pos.attacks_from<BISHOP>(checksq);
+ // If queen and king are far we can safely remove all the squares attacked
+ // in the other direction becuase are not reachable by the king anyway.
+ if (squares_between(ksq, checksq) || (RookPseudoAttacks[checksq] & (1ULL << ksq)))
+ sliderAttacks |= QueenPseudoAttacks[checksq];
+
+ // Otherwise, if king and queen are adjacent and on a diagonal line, we need to
+ // use real rook attacks to check if king is safe to move in the other direction.
+ // For example: king in B2, queen in A1 a knight in B1, and we can safely move to C1.
else
sliderAttacks |= BishopPseudoAttacks[checksq] | pos.attacks_from<ROOK>(checksq);
+
default:
break;
}
} while (b);
// Generate evasions for king, capture and non capture moves
- b = pos.attacks_from<KING>(ksq) & ~pos.pieces_of_color(us) & ~sliderAttacks;
+ b = pos.attacks_from<KING>(ksq) & ~pos.pieces(us) & ~sliderAttacks;
from = ksq;
SERIALIZE_MOVES(b);
Bitboard b1, b2, dc1, dc2, pawnPushes, emptySquares;
Bitboard pawns = pos.pieces(PAWN, Us);
Bitboard pawnsOn7 = pawns & TRank7BB;
- Bitboard enemyPieces = (Type == MV_CAPTURE ? target : pos.pieces_of_color(Them));
+ Bitboard enemyPieces = (Type == MV_CAPTURE ? target : pos.pieces(Them));
// Pre-calculate pawn pushes before changing emptySquares definition
if (Type != MV_CAPTURE)
Color them = opposite_color(us);
Square ksq = pos.king_square(us);
+ CastleRight f = CastleRight((Side == KING_SIDE ? WHITE_OO : WHITE_OOO) << us);
assert(pos.piece_on(ksq) == make_piece(us, KING));
- Square rsq = (Side == KING_SIDE ? pos.initial_kr_square(us) : pos.initial_qr_square(us));
+ Square rsq = pos.castle_rook_square(f);
Square s1 = relative_square(us, Side == KING_SIDE ? SQ_G1 : SQ_C1);
Square s2 = relative_square(us, Side == KING_SIDE ? SQ_F1 : SQ_D1);
Square s;
// It is a bit complicated to correctly handle Chess960
for (s = Min(ksq, s1); s <= Max(ksq, s1); s++)
- if ( (s != ksq && s != rsq && pos.square_is_occupied(s))
- ||(pos.attackers_to(s) & pos.pieces_of_color(them)))
+ if ( (s != ksq && s != rsq && !pos.square_is_empty(s))
+ ||(pos.attackers_to(s) & pos.pieces(them)))
illegal = true;
for (s = Min(rsq, s2); s <= Max(rsq, s2); s++)
- if (s != ksq && s != rsq && pos.square_is_occupied(s))
+ if (s != ksq && s != rsq && !pos.square_is_empty(s))
illegal = true;
if ( Side == QUEEN_SIDE