From: Marco Costalba Date: Mon, 27 Feb 2012 11:11:18 +0000 (+0100) Subject: Micro-optmize castling moves X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=34178205fc762638e633a61ecc45360e1662bdee Micro-optmize castling moves Pre compute castle path so to quickly test for impeded rule. This speeds up perft on starting position of more than 2%. No functional change Signed-off-by: Marco Costalba --- diff --git a/src/movegen.cpp b/src/movegen.cpp index 52d358a6..0301e906 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -40,7 +40,7 @@ namespace { const CastleRight CR[] = { Side ? WHITE_OOO : WHITE_OO, Side ? BLACK_OOO : BLACK_OO }; - if (!pos.can_castle(CR[us])) + if (pos.castle_impeded(CR[us]) || !pos.can_castle(CR[us])) return mlist; // After castling, the rook and king final positions are the same in Chess960 @@ -48,24 +48,15 @@ namespace { Square kfrom = pos.king_square(us); Square rfrom = pos.castle_rook_square(CR[us]); Square kto = relative_square(us, Side == KING_SIDE ? SQ_G1 : SQ_C1); - Square rto = relative_square(us, Side == KING_SIDE ? SQ_F1 : SQ_D1); Bitboard enemies = pos.pieces(~us); assert(!pos.in_check()); assert(pos.piece_on(kfrom) == make_piece(us, KING)); assert(pos.piece_on(rfrom) == make_piece(us, ROOK)); - // Unimpeded rule: All the squares between the king's initial and final squares - // (including the final square), and all the squares between the rook's initial - // and final squares (including the final square), must be vacant except for - // the king and castling rook. - for (Square s = std::min(rfrom, rto), e = std::max(rfrom, rto); s <= e; s++) - if (s != kfrom && s != rfrom && !pos.square_is_empty(s)) - return mlist; - for (Square s = std::min(kfrom, kto), e = std::max(kfrom, kto); s <= e; s++) - if ( (s != kfrom && s != rfrom && !pos.square_is_empty(s)) - ||(pos.attackers_to(s) & enemies)) + if ( s != kfrom // We are not in check + && (pos.attackers_to(s) & enemies)) return mlist; // Because we generate only legal castling moves we need to verify that diff --git a/src/position.cpp b/src/position.cpp index bf415b34..537674c9 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -242,14 +242,27 @@ void Position::from_fen(const string& fenStr, bool isChess960) { /// Position::set_castle_right() is an helper function used to set castling /// rights given the corresponding color and the rook starting square. -void Position::set_castle_right(Color c, Square rsq) { +void Position::set_castle_right(Color c, Square rfrom) { - int f = (rsq < king_square(c) ? WHITE_OOO : WHITE_OO) << c; + Square kfrom = king_square(c); + bool kingSide = kfrom < rfrom; + int cr = (kingSide ? WHITE_OO : WHITE_OOO) << c; - st->castleRights |= f; - castleRightsMask[king_square(c)] |= f; - castleRightsMask[rsq] |= f; - castleRookSquare[f] = rsq; + st->castleRights |= cr; + castleRightsMask[kfrom] |= cr; + castleRightsMask[rfrom] |= cr; + castleRookSquare[cr] = rfrom; + + Square kto = relative_square(c, kingSide ? SQ_G1 : SQ_C1); + Square rto = relative_square(c, kingSide ? SQ_F1 : SQ_D1); + + for (Square s = std::min(rfrom, rto); s <= std::max(rfrom, rto); s++) + if (s != kfrom && s != rfrom) + castlePath[cr] |= s; + + for (Square s = std::min(kfrom, kto); s <= std::max(kfrom, kto); s++) + if (s != kfrom && s != rfrom) + castlePath[cr] |= s; } diff --git a/src/position.h b/src/position.h index 2bbd43fd..30c25652 100644 --- a/src/position.h +++ b/src/position.h @@ -127,6 +127,7 @@ public: // Castling rights bool can_castle(CastleRight f) const; bool can_castle(Color c) const; + bool castle_impeded(CastleRight f) const; Square castle_rook_square(CastleRight f) const; // Bitboards for pinned pieces and discovered check candidates @@ -207,7 +208,7 @@ private: // Initialization helper functions (used while setting up a position) void clear(); void put_piece(Piece p, Square s); - void set_castle_right(Color c, Square rsq); + void set_castle_right(Color c, Square rfrom); bool move_is_legal(const Move m) const; // Helper template functions @@ -242,6 +243,7 @@ private: // Other info int castleRightsMask[64]; // [square] Square castleRookSquare[16]; // [castleRight] + Bitboard castlePath[16]; // [castleRight] StateInfo startState; int64_t nodes; int startPosPly; @@ -331,6 +333,10 @@ inline bool Position::can_castle(Color c) const { return st->castleRights & ((WHITE_OO | WHITE_OOO) << c); } +inline bool Position::castle_impeded(CastleRight f) const { + return occupied & castlePath[f]; +} + inline Square Position::castle_rook_square(CastleRight f) const { return castleRookSquare[f]; }