From: Fabian Fichter Date: Sun, 6 Jun 2021 16:34:46 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=06e55ba94fa6ffa51c738c3746f8315a13102bd2;p=fairystockfish.git Merge official-stockfish/master No functional change. --- 06e55ba94fa6ffa51c738c3746f8315a13102bd2 diff --cc src/bitboard.cpp index d0f29c5,2da4d72..4bd4f7d --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@@ -31,31 -29,12 +31,32 @@@ uint8_t SquareDistance[SQUARE_NB][SQUAR Bitboard SquareBB[SQUARE_NB]; Bitboard LineBB[SQUARE_NB][SQUARE_NB]; + Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; -Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; -Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; - -Magic RookMagics[SQUARE_NB]; +Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard BoardSizeBB[FILE_NB][RANK_NB]; +RiderType AttackRiderTypes[PIECE_TYPE_NB]; +RiderType MoveRiderTypes[PIECE_TYPE_NB]; + +Magic RookMagicsH[SQUARE_NB]; +Magic RookMagicsV[SQUARE_NB]; Magic BishopMagics[SQUARE_NB]; +Magic CannonMagicsH[SQUARE_NB]; +Magic CannonMagicsV[SQUARE_NB]; +Magic HorseMagics[SQUARE_NB]; +Magic ElephantMagics[SQUARE_NB]; +Magic JanggiElephantMagics[SQUARE_NB]; +Magic CannonDiagMagics[SQUARE_NB]; +Magic NightriderMagics[SQUARE_NB]; +Magic GrasshopperMagicsH[SQUARE_NB]; +Magic GrasshopperMagicsV[SQUARE_NB]; +Magic GrasshopperMagicsD[SQUARE_NB]; + +Magic* magics[] = {BishopMagics, RookMagicsH, RookMagicsV, CannonMagicsH, CannonMagicsV, + HorseMagics, ElephantMagics, JanggiElephantMagics, CannonDiagMagics, NightriderMagics, + GrasshopperMagicsH, GrasshopperMagicsV, GrasshopperMagicsD}; namespace { @@@ -298,55 -82,40 +299,61 @@@ void Bitboards::init() for (unsigned i = 0; i < (1 << 16); ++i) PopCnt16[i] = uint8_t(std::bitset<16>(i).count()); - for (Square s = SQ_A1; s <= SQ_H8; ++s) - SquareBB[s] = (1ULL << s); - - for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) - for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) - SquareDistance[s1][s2] = std::max(distance(s1, s2), distance(s1, s2)); - - init_magics(ROOK, RookTable, RookMagics); - init_magics(BISHOP, BishopTable, BishopMagics); - - for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) + for (Square s = SQ_A1; s <= SQ_MAX; ++s) + SquareBB[s] = make_bitboard(s); + + for (File f = FILE_A; f <= FILE_MAX; ++f) + for (Rank r = RANK_1; r <= RANK_MAX; ++r) + BoardSizeBB[f][r] = forward_file_bb(BLACK, make_square(f, r)) | SquareBB[make_square(f, r)] | (f > FILE_A ? BoardSizeBB[f - 1][r] : Bitboard(0)); + + for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1) + for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2) + SquareDistance[s1][s2] = std::max(distance(s1, s2), distance(s1, s2)); + +#ifdef PRECOMPUTED_MAGICS + init_magics(RookTableH, RookMagicsH, RookDirectionsH, RookMagicHInit); + init_magics(RookTableV, RookMagicsV, RookDirectionsV, RookMagicVInit); + init_magics(BishopTable, BishopMagics, BishopDirections, BishopMagicInit); + init_magics(CannonTableH, CannonMagicsH, RookDirectionsH, CannonMagicHInit); + init_magics(CannonTableV, CannonMagicsV, RookDirectionsV, CannonMagicVInit); + init_magics(HorseTable, HorseMagics, HorseDirections, HorseMagicInit); + init_magics(ElephantTable, ElephantMagics, ElephantDirections, ElephantMagicInit); + init_magics(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections, JanggiElephantMagicInit); + init_magics(CannonDiagTable, CannonDiagMagics, BishopDirections, CannonDiagMagicInit); + init_magics(NightriderTable, NightriderMagics, HorseDirections, NightriderMagicInit); + init_magics(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH, GrasshopperMagicHInit); + init_magics(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV, GrasshopperMagicVInit); + init_magics(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD, GrasshopperMagicDInit); +#else + init_magics(RookTableH, RookMagicsH, RookDirectionsH); + init_magics(RookTableV, RookMagicsV, RookDirectionsV); + init_magics(BishopTable, BishopMagics, BishopDirections); + init_magics(CannonTableH, CannonMagicsH, RookDirectionsH); + init_magics(CannonTableV, CannonMagicsV, RookDirectionsV); + init_magics(HorseTable, HorseMagics, HorseDirections); + init_magics(ElephantTable, ElephantMagics, ElephantDirections); + init_magics(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections); + init_magics(CannonDiagTable, CannonDiagMagics, BishopDirections); + init_magics(NightriderTable, NightriderMagics, HorseDirections); + init_magics(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH); + init_magics(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV); + init_magics(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD); +#endif + + init_pieces(); + + for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1) { - PawnAttacks[WHITE][s1] = pawn_attacks_bb(square_bb(s1)); - PawnAttacks[BLACK][s1] = pawn_attacks_bb(square_bb(s1)); - - for (int step : {-9, -8, -7, -1, 1, 7, 8, 9} ) - PseudoAttacks[KING][s1] |= safe_destination(s1, step); - - for (int step : {-17, -15, -10, -6, 6, 10, 15, 17} ) - PseudoAttacks[KNIGHT][s1] |= safe_destination(s1, step); - - PseudoAttacks[QUEEN][s1] = PseudoAttacks[BISHOP][s1] = attacks_bb(s1, 0); - PseudoAttacks[QUEEN][s1] |= PseudoAttacks[ ROOK][s1] = attacks_bb< ROOK>(s1, 0); - for (PieceType pt : { BISHOP, ROOK }) - for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) + for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2) + { - if (PseudoAttacks[pt][s1] & s2) + if (PseudoAttacks[WHITE][pt][s1] & s2) - LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2; + { - LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2; - BetweenBB[s1][s2] = (attacks_bb(pt, s1, square_bb(s2)) & attacks_bb(pt, s2, square_bb(s1))); ++ LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2; ++ BetweenBB[s1][s2] = (attacks_bb(WHITE, pt, s1, square_bb(s2)) & attacks_bb(WHITE, pt, s2, square_bb(s1))); + } + BetweenBB[s1][s2] |= s2; + } } } diff --cc src/bitboard.h index 4d3b2ef,70835e8..b66f84b --- a/src/bitboard.h +++ b/src/bitboard.h @@@ -103,19 -75,11 +103,20 @@@ extern uint8_t PopCnt16[1 << 16] extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; extern Bitboard SquareBB[SQUARE_NB]; + extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; -extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; -extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; +extern Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard SquareBB[SQUARE_NB]; +extern Bitboard BoardSizeBB[FILE_NB][RANK_NB]; +extern RiderType AttackRiderTypes[PIECE_TYPE_NB]; +extern RiderType MoveRiderTypes[PIECE_TYPE_NB]; +#ifdef LARGEBOARDS +int popcount(Bitboard b); // required for 128 bit pext +#endif /// Magic holds all magic bitboards relevant data for a single square struct Magic { @@@ -295,29 -216,22 +296,32 @@@ inline Bitboard line_bb(Square s1, Squa } - /// between_bb() returns a bitboard representing squares that are linearly - /// between the two given squares (excluding the given squares). If the given - /// squares are not on a same file/rank/diagonal, we return 0. For instance, - /// between_bb(SQ_C4, SQ_F7) will return a bitboard with squares D5 and E6. + /// between_bb(s1, s2) returns a bitboard representing the squares in the semi-open + /// segment between the squares s1 and s2 (excluding s1 but including s2). If the + /// given squares are not on a same file/rank/diagonal, it returns s2. For instance, + /// between_bb(SQ_C4, SQ_F7) will return a bitboard with squares D5, E6 and F7, but + /// between_bb(SQ_E6, SQ_F8) will return a bitboard with the square F8. This trick + /// allows to generate non-king evasion moves faster: the defending piece must either + /// interpose itself to cover the check or capture the checking piece. inline Bitboard between_bb(Square s1, Square s2) { - Bitboard b = line_bb(s1, s2) & ((AllSquares << s1) ^ (AllSquares << s2)); - return b & (b - 1); //exclude lsb + assert(is_ok(s1) && is_ok(s2)); + return BetweenBB[s1][s2]; } +inline Bitboard between_bb(Square s1, Square s2, PieceType pt) { + if (pt == HORSE) + return PseudoAttacks[WHITE][WAZIR][s2] & PseudoAttacks[WHITE][FERS][s1]; + else if (pt == JANGGI_ELEPHANT) + return (PseudoAttacks[WHITE][WAZIR][s2] & PseudoAttacks[WHITE][ALFIL][s1]) + | (PseudoAttacks[WHITE][KNIGHT][s2] & PseudoAttacks[WHITE][FERS][s1]); + else + return between_bb(s1, s2); +} + - /// forward_ranks_bb() returns a bitboard representing the squares on the ranks - /// in front of the given one, from the point of view of the given color. For instance, + /// forward_ranks_bb() returns a bitboard representing the squares on the ranks in + /// front of the given one, from the point of view of the given color. For instance, /// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2. constexpr Bitboard forward_ranks_bb(Color c, Square s) { diff --cc src/movegen.cpp index 4b1061b,742dbf4..58bf95e --- a/src/movegen.cpp +++ b/src/movegen.cpp @@@ -245,9 -156,9 +245,9 @@@ namespace if (pos.ep_square() != SQ_NONE) { - assert(rank_of(pos.ep_square()) == relative_rank(Us, RANK_6)); + assert(relative_rank(Them, rank_of(pos.ep_square()), pos.max_rank()) <= Rank(pos.double_step_rank_max() + 1)); - // An en passant capture cannot resolve a discovered check. + // An en passant capture cannot resolve a discovered check if (Type == EVASIONS && (target & (pos.ep_square() + Up))) return moveList; @@@ -348,19 -218,8 +348,19 @@@ target = ~pos.pieces(); break; case EVASIONS: + { + if (pos.checkers() & pos.non_sliding_riders()) + { + target = ~pos.pieces(Us); + break; + } - target = between_bb(pos.square(Us), lsb(pos.checkers())) | pos.checkers(); + target = between_bb(pos.square(Us), lsb(pos.checkers())); + // Leaper attacks can not be blocked + Square checksq = lsb(pos.checkers()); + if (LeaperAttacks[~Us][type_of(pos.piece_on(checksq))][checksq] & pos.square(Us)) + target = pos.checkers(); break; + } case NON_EVASIONS: target = ~pos.pieces(Us); break; diff --cc src/position.cpp index 293dbf8,772e454..5bfa89b --- a/src/position.cpp +++ b/src/position.cpp @@@ -511,10 -317,10 +511,10 @@@ void Position::set_castling_right(Colo castlingRightsMask[rfrom] |= cr; castlingRookSquare[cr] = rfrom; - Square kto = relative_square(c, cr & KING_SIDE ? SQ_G1 : SQ_C1); - Square rto = relative_square(c, cr & KING_SIDE ? SQ_F1 : SQ_D1); + Square kto = make_square(cr & KING_SIDE ? castling_kingside_file() : castling_queenside_file(), castling_rank(c)); + Square rto = kto + (cr & KING_SIDE ? WEST : EAST); - castlingPath[cr] = (between_bb(rfrom, rto) | between_bb(kfrom, kto) | rto | kto) + castlingPath[cr] = (between_bb(rfrom, rto) | between_bb(kfrom, kto)) & ~(kfrom | rfrom); } @@@ -1191,10 -613,8 +1191,10 @@@ bool Position::pseudo_legal(const Move if (more_than_one(checkers())) return false; - // Our move must be a blocking interposition or a capture of the checking piece - if (!(between_bb(square(us), lsb(checkers())) & to)) + // Our move must be a blocking evasion or a capture of the checking piece + Square checksq = lsb(checkers()); - if ( !((between_bb(checksq, square(us)) | checkers()) & to) ++ if ( !(between_bb(square(us), lsb(checkers())) & to) + || ((LeaperAttacks[~us][type_of(piece_on(checksq))][checksq] & square(us)) && !(checkers() & to))) return false; } // In case of king moves under check we have to remove king so as to catch