Skip to content

Commit

Permalink
speed up for legal
Browse files Browse the repository at this point in the history
  • Loading branch information
PikaCat committed Oct 1, 2022
1 parent d699bdf commit 3c764c1
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 19 deletions.
14 changes: 3 additions & 11 deletions src/movegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,13 @@ ExtMove* generate<EVASIONS>(const Position& pos, ExtMove* moveList) {
template<>
ExtMove* generate<LEGAL>(const Position& pos, ExtMove* moveList) {

Color us = pos.side_to_move();
Bitboard pinned = pos.blockers_for_king(us) & pos.pieces(us);
Square ksq = pos.square<KING>(us);
ExtMove* cur = moveList;

// We have to take special cares about the cannon and checks
bool inCheck = pos.checkers();
bool notOk = inCheck || (attacks_bb<ROOK>(ksq) & pos.pieces(~us, CANNON));

moveList = inCheck ? generate<EVASIONS>(pos, moveList)
: generate<PSEUDO_LEGAL>(pos, moveList);
moveList = pos.checkers() ? generate<EVASIONS>(pos, moveList)
: generate<PSEUDO_LEGAL>(pos, moveList);

while (cur != moveList)
// A move is always legal when not moving the king or a pinned piece
if ((notOk || (pinned && pinned & from_sq(*cur)) || from_sq(*cur) == ksq) && !pos.legal(*cur))
if (!pos.legal(*cur))
*cur = (--moveList)->move;
else
++cur;
Expand Down
25 changes: 17 additions & 8 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,20 @@ Position& Position::set(const string& fenStr, StateInfo* si, Thread* th) {

void Position::set_check_info(StateInfo* si) const {

si->blockersForKing[WHITE] = blockers_for_king(pieces(BLACK), square<KING>(WHITE), si->pinners[BLACK]);
si->blockersForKing[BLACK] = blockers_for_king(pieces(WHITE), square<KING>(BLACK), si->pinners[WHITE]);
Color us = sideToMove;
Square uksq = square<KING>( us);
Square oksq = square<KING>(~us);

Square ksq = square<KING>(~sideToMove);
si->blockersForKing[ us] = blockers_for_king(pieces(~us), uksq, si->pinners[~us]);
si->blockersForKing[~us] = blockers_for_king(pieces( us), oksq, si->pinners[ us]);

// We have to take special cares about the cannon and checks
si->needSlowCheck = checkers() || (attacks_bb<ROOK>(uksq) & pieces(~us, CANNON));

si->checkSquares[PAWN] = pawn_attacks_to_bb(sideToMove, ksq);
si->checkSquares[KNIGHT] = attacks_bb<KNIGHT_TO>(ksq, pieces());
si->checkSquares[CANNON] = attacks_bb<CANNON>(ksq, pieces());
si->checkSquares[ROOK] = attacks_bb<ROOK>(ksq, pieces());
si->checkSquares[PAWN] = pawn_attacks_to_bb(sideToMove, oksq);
si->checkSquares[KNIGHT] = attacks_bb<KNIGHT_TO>(oksq, pieces());
si->checkSquares[CANNON] = attacks_bb<CANNON>(oksq, pieces());
si->checkSquares[ROOK] = attacks_bb<ROOK>(oksq, pieces());
si->checkSquares[KING] = si->checkSquares[ADVISOR] = si->checkSquares[BISHOP] = 0;
}

Expand Down Expand Up @@ -323,12 +328,16 @@ bool Position::legal(Move m) const {
Square from = from_sq(m);
Square to = to_sq(m);
Bitboard occupied = (pieces() ^ from) | to;
Square ksq = type_of(moved_piece(m)) == KING ? to : square<KING>(us);

assert(color_of(moved_piece(m)) == us);
assert(piece_on(square<KING>(us)) == make_piece(us, KING));

// A non-king move is always legal when not moving the king or a pinned piece if we don't need slow check
if (!st->needSlowCheck && ksq != to && !(blockers_for_king(us) & from))
return true;

// Flying general rule
Square ksq = type_of(moved_piece(m)) == KING ? to : square<KING>(us);
if (attacks_bb<ROOK>(ksq, occupied) & pieces(~us, KING))
return false;

Expand Down
1 change: 1 addition & 0 deletions src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct StateInfo {
Bitboard blockersForKing[COLOR_NB];
Bitboard pinners[COLOR_NB];
Bitboard checkSquares[PIECE_TYPE_NB];
bool needSlowCheck;
Piece capturedPiece;
uint16_t chased;
Move move;
Expand Down

0 comments on commit 3c764c1

Please sign in to comment.