Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Thu, 1 Jul 2021 21:58:55 +0000 (23:58 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Thu, 1 Jul 2021 21:58:55 +0000 (23:58 +0200)
No functional change.

1  2 
src/movegen.cpp

diff --cc src/movegen.cpp
@@@ -108,30 -57,19 +108,26 @@@ namespace 
      constexpr Direction UpRight  = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
      constexpr Direction UpLeft   = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
  
-     const Square ksq = pos.count<KING>(Them) ? pos.square<KING>(Them) : SQ_NONE;
 -    const Square ksq = pos.square<KING>(Them);
 +    Bitboard TRank8BB = pos.mandatory_pawn_promotion() ? rank_bb(relative_rank(Us, pos.promotion_rank(), pos.max_rank()))
 +                                                       : zone_bb(Us, pos.promotion_rank(), pos.max_rank());
 +    Bitboard TRank7BB = shift<Down>(TRank8BB);
 +    // Define squares a pawn can pass during a double step
 +    Bitboard  TRank3BB =  forward_ranks_bb(Us, relative_rank(Us, pos.double_step_rank_min(), pos.max_rank()))
 +                        & ~shift<Up>(forward_ranks_bb(Us, relative_rank(Us, pos.double_step_rank_max(), pos.max_rank())));
 +
-     Bitboard emptySquares;
++    const Square ksq = pos.count<KING>(Them) ? pos.square<KING>(Them) : SQ_NONE;
+     const Bitboard emptySquares = Type == QUIETS || Type == QUIET_CHECKS ? target : ~pos.pieces();
+     const Bitboard enemies      = Type == EVASIONS ? pos.checkers()
+                                 : Type == CAPTURES ? target : pos.pieces(Them);
  
      Bitboard pawnsOn7    = pos.pieces(Us, PAWN) &  TRank7BB;
 -    Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & ~TRank7BB;
 +    Bitboard pawnsNotOn7 = pos.pieces(Us, PAWN) & (pos.mandatory_pawn_promotion() ? ~TRank7BB : AllSquares);
  
      // Single and double pawn pushes, no promotions
      if (Type != CAPTURES)
      {
-         emptySquares = (Type == QUIETS || Type == QUIET_CHECKS ? target : ~pos.pieces() & pos.board_bb(Us, PAWN));
          Bitboard b1 = shift<Up>(pawnsNotOn7)   & emptySquares;
 -        Bitboard b2 = shift<Up>(b1 & TRank3BB) & emptySquares;
 +        Bitboard b2 = pos.double_step_enabled() ? shift<Up>(b1 & TRank3BB) & emptySquares : Bitboard(0);
  
          if (Type == EVASIONS) // Consider only blocking squares
          {
              b2 &= target;
          }
  
 -        if (Type == QUIET_CHECKS)
 +        if (Type == QUIET_CHECKS && pos.count<KING>(Them))
          {
-             b1 &= pawn_attacks_bb(Them, ksq);
-             b2 &= pawn_attacks_bb(Them, ksq);
-             // Add pawn pushes which give discovered check. This is possible only
-             // if the pawn is not on the same file as the enemy king, because we
-             // don't generate captures. Note that a possible discovered check
-             // promotion has been already generated amongst the captures.
-             Bitboard dcCandidateQuiets = pos.blockers_for_king(Them) & pawnsNotOn7;
-             if (dcCandidateQuiets)
-             {
-                 Bitboard dc1 = shift<Up>(dcCandidateQuiets) & emptySquares & ~file_bb(ksq);
-                 Bitboard dc2 = pos.double_step_enabled() ? shift<Up>(dc1 & TRank3BB) & emptySquares : Bitboard(0);
-                 b1 |= dc1;
-                 b2 |= dc2;
-             }
+             // To make a quiet check, you either make a direct check by pushing a pawn
+             // or push a blocker pawn that is not on the same file as the enemy king.
+             // Discovered check promotion has been already generated amongst the captures.
+             Bitboard dcCandidatePawns = pos.blockers_for_king(Them) & ~file_bb(ksq);
+             b1 &= pawn_attacks_bb(Them, ksq) | shift<   Up>(dcCandidatePawns);
+             b2 &= pawn_attacks_bb(Them, ksq) | shift<Up+Up>(dcCandidatePawns);
          }
  
          while (b1)
          Bitboard b2 = shift<UpLeft >(pawnsOn7) & enemies;
          Bitboard b3 = shift<Up     >(pawnsOn7) & emptySquares;
  
+         if (Type == EVASIONS)
+             b3 &= target;
          while (b1)
 -            moveList = make_promotions<Type, UpRight>(moveList, pop_lsb(b1), ksq);
 +            moveList = make_promotions<Us, Type, UpRight>(pos, moveList, pop_lsb(b1));
  
          while (b2)
 -            moveList = make_promotions<Type, UpLeft >(moveList, pop_lsb(b2), ksq);
 +            moveList = make_promotions<Us, Type, UpLeft >(pos, moveList, pop_lsb(b2));
  
          while (b3)
 -            moveList = make_promotions<Type, Up     >(moveList, pop_lsb(b3), ksq);
 +            moveList = make_promotions<Us, Type, Up     >(pos, moveList, pop_lsb(b3));
 +    }
 +
 +    // Sittuyin promotions
 +    if (pos.sittuyin_promotion() && (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS))
 +    {
 +        Bitboard pawns = pos.pieces(Us, PAWN);
 +        // Pawns need to be on diagonals on opponent's half if there is more than one pawn
 +        if (pos.count<PAWN>(Us) > 1)
 +            pawns &=  (  PseudoAttacks[Us][BISHOP][make_square(FILE_A, relative_rank(Us, RANK_1, pos.max_rank()))]
 +                       | PseudoAttacks[Us][BISHOP][make_square(pos.max_file(), relative_rank(Us, RANK_1, pos.max_rank()))])
 +                    & forward_ranks_bb(Us, relative_rank(Us, Rank((pos.max_rank() - 1) / 2), pos.max_rank()));
 +        while (pawns)
 +        {
 +            Square from = pop_lsb(pawns);
 +            for (PieceType pt : pos.promotion_piece_types())
 +            {
 +                if (pos.promotion_limit(pt) && pos.promotion_limit(pt) <= pos.count(Us, pt))
 +                    continue;
 +                Bitboard b = (pos.attacks_from(Us, pt, from) & ~pos.pieces()) | from;
 +                if (Type == EVASIONS)
 +                    b &= target;
 +
 +                while (b)
 +                {
 +                    Square to = pop_lsb(b);
 +                    if (!(attacks_bb(Us, pt, to, pos.pieces() ^ from) & pos.pieces(Them)))
 +                        *moveList++ = make<PROMOTION>(from, to, pt);
 +                }
 +            }
 +        }
      }
  
      // Standard and en passant captures