Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Sun, 6 Jun 2021 16:34:46 +0000 (18:34 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sun, 6 Jun 2021 16:34:46 +0000 (18:34 +0200)
No functional change.

1  2 
src/bitboard.cpp
src/bitboard.h
src/movegen.cpp
src/position.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<File>(s1, s2), distance<Rank>(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<File>(s1, s2), distance<Rank>(s1, s2));
 +
 +#ifdef PRECOMPUTED_MAGICS
 +  init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH, RookMagicHInit);
 +  init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV, RookMagicVInit);
 +  init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections, BishopMagicInit);
 +  init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH, CannonMagicHInit);
 +  init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV, CannonMagicVInit);
 +  init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections, HorseMagicInit);
 +  init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections, ElephantMagicInit);
 +  init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections, JanggiElephantMagicInit);
 +  init_magics<HOPPER>(CannonDiagTable, CannonDiagMagics, BishopDirections, CannonDiagMagicInit);
 +  init_magics<RIDER>(NightriderTable, NightriderMagics, HorseDirections, NightriderMagicInit);
 +  init_magics<HOPPER>(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH, GrasshopperMagicHInit);
 +  init_magics<HOPPER>(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV, GrasshopperMagicVInit);
 +  init_magics<HOPPER>(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD, GrasshopperMagicDInit);
 +#else
 +  init_magics<RIDER>(RookTableH, RookMagicsH, RookDirectionsH);
 +  init_magics<RIDER>(RookTableV, RookMagicsV, RookDirectionsV);
 +  init_magics<RIDER>(BishopTable, BishopMagics, BishopDirections);
 +  init_magics<HOPPER>(CannonTableH, CannonMagicsH, RookDirectionsH);
 +  init_magics<HOPPER>(CannonTableV, CannonMagicsV, RookDirectionsV);
 +  init_magics<LAME_LEAPER>(HorseTable, HorseMagics, HorseDirections);
 +  init_magics<LAME_LEAPER>(ElephantTable, ElephantMagics, ElephantDirections);
 +  init_magics<LAME_LEAPER>(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections);
 +  init_magics<HOPPER>(CannonDiagTable, CannonDiagMagics, BishopDirections);
 +  init_magics<RIDER>(NightriderTable, NightriderMagics, HorseDirections);
 +  init_magics<HOPPER>(GrasshopperTableH, GrasshopperMagicsH, GrasshopperDirectionsH);
 +  init_magics<HOPPER>(GrasshopperTableV, GrasshopperMagicsV, GrasshopperDirectionsV);
 +  init_magics<HOPPER>(GrasshopperTableD, GrasshopperMagicsD, GrasshopperDirectionsD);
 +#endif
 +
 +  init_pieces();
 +
 +  for (Square s1 = SQ_A1; s1 <= SQ_MAX; ++s1)
    {
 -      PawnAttacks[WHITE][s1] = pawn_attacks_bb<WHITE>(square_bb(s1));
 -      PawnAttacks[BLACK][s1] = pawn_attacks_bb<BLACK>(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<BISHOP>(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
@@@ -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
@@@ -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;
  
              target = ~pos.pieces();
              break;
          case EVASIONS:
 +        {
 +            if (pos.checkers() & pos.non_sliding_riders())
 +            {
 +                target = ~pos.pieces(Us);
 +                break;
 +            }
-             target = between_bb(pos.square<KING>(Us), lsb(pos.checkers())) | pos.checkers();
+             target = between_bb(pos.square<KING>(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<KING>(Us))
 +                target = pos.checkers();
              break;
 +        }
          case NON_EVASIONS:
              target = ~pos.pieces(Us);
              break;
@@@ -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<KING>(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<KING>(us)) | checkers()) & to)
++          if (  !(between_bb(square<KING>(us), lsb(checkers())) & to)
 +              || ((LeaperAttacks[~us][type_of(piece_on(checksq))][checksq] & square<KING>(us)) && !(checkers() & to)))
                return false;
        }
        // In case of king moves under check we have to remove king so as to catch