Merge official-stockfish/master
authorFabian Fichter <ianfab@users.noreply.github.com>
Fri, 7 Aug 2020 15:43:26 +0000 (17:43 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Fri, 7 Aug 2020 15:43:26 +0000 (17:43 +0200)
No functional change.

1  2 
src/bitboard.cpp
src/evaluate.cpp
src/material.cpp
src/movegen.cpp
src/movepick.cpp
src/pawns.cpp
src/position.cpp
src/search.cpp
src/uci.cpp

@@@ -250,79 -71,44 +250,76 @@@ void Bitboards::init() 
    for (unsigned i = 0; i < (1 << 16); ++i)
        PopCnt16[i] = 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));
 -
 -  Direction RookDirections[] = { NORTH, EAST, SOUTH, WEST };
 -  Direction BishopDirections[] = { NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST };
 -
 -  init_magics(RookTable, RookMagics, RookDirections);
 -  init_magics(BishopTable, BishopMagics, BishopDirections);
 +  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);
 +#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);
 +#endif
  
+   // Helper returning the target bitboard of a step from a square
+   auto landing_square_bb = [&](Square s, int step)
+   {
+       Square to = Square(s + step);
 -      return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0);
++      return is_ok(to) && distance(s, to) < 4 ? square_bb(to) : Bitboard(0);
+   };
 -  for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
 +  for (Color c : { WHITE, BLACK })
 +      for (PieceType pt = PAWN; pt <= KING; ++pt)
 +      {
 +          const PieceInfo* pi = pieceMap.find(pt)->second;
 +
 +          for (Square s = SQ_A1; s <= SQ_MAX; ++s)
 +          {
 +              for (Direction d : pi->stepsCapture)
 +              {
-                   Square to = s + Direction(c == WHITE ? d : -d);
-                   if (is_ok(to) && distance(s, to) < 4)
-                   {
-                       PseudoAttacks[c][pt][s] |= to;
-                       if (!pi->lameLeaper)
-                           LeaperAttacks[c][pt][s] |= to;
-                   }
++                  PseudoAttacks[c][pt][s] |= landing_square_bb(s, c == WHITE ? d : -d);
++                  if (!pi->lameLeaper)
++                      LeaperAttacks[c][pt][s] |= landing_square_bb(s, c == WHITE ? d : -d);
 +              }
 +              for (Direction d : pi->stepsQuiet)
 +              {
-                   Square to = s + Direction(c == WHITE ? d : -d);
-                   if (is_ok(to) && distance(s, to) < 4)
-                   {
-                       PseudoMoves[c][pt][s] |= to;
-                       if (!pi->lameLeaper)
-                           LeaperMoves[c][pt][s] |= to;
-                   }
++                  PseudoMoves[c][pt][s] |= landing_square_bb(s, c == WHITE ? d : -d);
++                  if (!pi->lameLeaper)
++                      LeaperMoves[c][pt][s] |= landing_square_bb(s, c == WHITE ? d : -d);
 +              }
 +              PseudoAttacks[c][pt][s] |= sliding_attack<RIDER>(pi->sliderCapture, s, 0, c);
 +              PseudoAttacks[c][pt][s] |= sliding_attack<RIDER>(pi->hopperCapture, s, 0, c);
 +              PseudoMoves[c][pt][s] |= sliding_attack<RIDER>(pi->sliderQuiet, s, 0, c);
 +              PseudoMoves[c][pt][s] |= sliding_attack<RIDER>(pi->hopperQuiet, s, 0, c);
 +          }
 +      }
 +
 +  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] |= landing_square_bb(s1, step);
 -
 -      for (int step : {-17, -15, -10, -6, 6, 10, 15, 17} )
 -         PseudoAttacks[KNIGHT][s1] |= landing_square_bb(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)
 -              if (PseudoAttacks[pt][s1] & s2)
 -                  LineBB[s1][s2] = (attacks_bb(pt, s1, 0) & attacks_bb(pt, s2, 0)) | s1 | s2;
 +          for (Square s2 = SQ_A1; s2 <= SQ_MAX; ++s2)
 +              if (PseudoAttacks[WHITE][pt][s1] & s2)
 +                  LineBB[s1][s2] = (attacks_bb(WHITE, pt, s1, 0) & attacks_bb(WHITE, pt, s2, 0)) | s1 | s2;
    }
  }
  
@@@ -92,20 -90,16 +92,16 @@@ namespace 
  
    // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
    // indexed by piece type and number of attacked squares in the mobility area.
- #ifdef LARGEBOARDS
-   constexpr Score MobilityBonus[][38] = {
- #else
--  constexpr Score MobilityBonus[][32] = {
- #endif
-     { S(-62,-81), S(-53,-56), S(-12,-30), S( -4,-14), S(  3,  8), S( 13, 15), // Knights
++  constexpr Score MobilityBonus[][4 * RANK_NB] = {
+     { S(-62,-81), S(-53,-56), S(-12,-30), S( -4,-14), S(  3,  8), S( 13, 15), // Knight
        S( 22, 23), S( 28, 27), S( 33, 33) },
-     { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishops
+     { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
        S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
        S( 91, 88), S( 98, 97) },
-     { S(-58,-76), S(-27,-18), S(-15, 28), S(-10, 55), S( -5, 69), S( -2, 82), // Rooks
+     { S(-58,-76), S(-27,-18), S(-15, 28), S(-10, 55), S( -5, 69), S( -2, 82), // Rook
        S(  9,112), S( 16,118), S( 30,132), S( 29,142), S( 32,155), S( 38,165),
        S( 46,166), S( 48,169), S( 58,171) },
-     { S(-39,-36), S(-21,-15), S(  3,  8), S(  3, 18), S( 14, 34), S( 22, 54), // Queens
+     { S(-39,-36), S(-21,-15), S(  3,  8), S(  3, 18), S( 14, 34), S( 22, 54), // Queen
        S( 28, 61), S( 41, 73), S( 43, 79), S( 48, 92), S( 56, 94), S( 60,104),
        S( 60,113), S( 66,120), S( 67,123), S( 70,126), S( 71,133), S( 73,136),
        S( 79,140), S( 88,143), S( 88,148), S( 99,166), S(102,170), S(102,175),
    template<Tracing T> template<Color Us>
    void Evaluation<T>::initialize() {
  
-     constexpr Color     Them = (Us == WHITE ? BLACK : WHITE);
+     constexpr Color     Them = ~Us;
      constexpr Direction Up   = pawn_push(Us);
      constexpr Direction Down = -Up;
 -    constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
 +    Bitboard LowRanks = rank_bb(relative_rank(Us, RANK_2, pos.max_rank())) | rank_bb(relative_rank(Us, RANK_3, pos.max_rank()));
  
 -    const Square ksq = pos.square<KING>(Us);
 +    const Square ksq = pos.count<KING>(Us) ? pos.square<KING>(Us) : SQ_NONE;
  
      Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
  
  
  
    // Evaluation::pieces() scores pieces of a given color and type
 -  template<Tracing T> template<Color Us, PieceType Pt>
 -  Score Evaluation<T>::pieces() {
 +  template<Tracing T> template<Color Us>
 +  Score Evaluation<T>::pieces(PieceType Pt) {
  
-     constexpr Color     Them = (Us == WHITE ? BLACK : WHITE);
+     constexpr Color     Them = ~Us;
      constexpr Direction Down = -pawn_push(Us);
      constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
                                                     : Rank5BB | Rank4BB | Rank3BB);
                  score += MinorBehindPawn;
  
              // Penalty if the piece is far from the king
 +            if (pos.count<KING>(Us))
-             score -= KingProtector * distance(s, pos.square<KING>(Us));
+             score -= KingProtector * distance(pos.square<KING>(Us), s);
  
              if (Pt == BISHOP)
              {
      return score;
    }
  
 +  // Evaluation::hand() scores pieces of a given color and type in hand
 +  template<Tracing T> template<Color Us>
 +  Score Evaluation<T>::hand(PieceType pt) {
 +
-     constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
++    constexpr Color Them = ~Us;
 +
 +    Score score = SCORE_ZERO;
 +
 +    if (pos.count_in_hand(Us, pt))
 +    {
 +        Bitboard b = pos.drop_region(Us, pt) & ~pos.pieces() & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
 +        if ((b & kingRing[Them]) && pt != SHOGI_PAWN)
 +        {
 +            kingAttackersCountInHand[Us] += pos.count_in_hand(Us, pt);
 +            kingAttackersWeightInHand[Us] += KingAttackWeights[std::min(int(pt), QUEEN + 1)] * pos.count_in_hand(Us, pt);
 +            kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
 +        }
 +        Bitboard theirHalf = pos.board_bb() & ~forward_ranks_bb(Them, relative_rank(Them, Rank((pos.max_rank() - 1) / 2), pos.max_rank()));
 +        mobility[Us] += DropMobility * popcount(b & theirHalf & ~attackedBy[Them][ALL_PIECES]);
 +        if (pos.promoted_piece_type(pt) != NO_PIECE_TYPE && pos.drop_promoted())
 +            score += make_score(std::max(PieceValue[MG][pos.promoted_piece_type(pt)] - PieceValue[MG][pt], VALUE_ZERO),
 +                                std::max(PieceValue[EG][pos.promoted_piece_type(pt)] - PieceValue[EG][pt], VALUE_ZERO)) / 4 * pos.count_in_hand(Us, pt);
 +        if (pos.enclosing_drop())
 +            mobility[Us] += make_score(500, 500) * popcount(b);
 +    }
 +
 +    return score;
 +  }
  
    // Evaluation::king() assigns bonuses and penalties to a king of a given color
    template<Tracing T> template<Color Us>
    Score Evaluation<T>::king() const {
  
-     constexpr Color    Them = (Us == WHITE ? BLACK : WHITE);
+     constexpr Color    Them = ~Us;
 -    constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
 -                                           : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
 +    Rank r = relative_rank(Us, std::min(Rank((pos.max_rank() - 1) / 2 + 1), pos.max_rank()), pos.max_rank());
 +    Bitboard Camp = pos.board_bb() & ~forward_ranks_bb(Us, r);
 +
 +    if (!pos.count<KING>(Us) || !pos.checking_permitted())
 +        return SCORE_ZERO;
  
      Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
 -    Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
 +    Bitboard queenChecks, knightChecks, pawnChecks, otherChecks;
      int kingDanger = 0;
      const Square ksq = pos.square<KING>(Us);
  
    template<Tracing T> template<Color Us>
    Score Evaluation<T>::space() const {
  
 -    if (pos.non_pawn_material() < SpaceThreshold)
 +    bool pawnsOnly = !(pos.pieces(Us) ^ pos.pieces(Us, PAWN));
 +
 +    if (pos.non_pawn_material() < SpaceThreshold && !pos.captures_to_hand() && !pawnsOnly)
          return SCORE_ZERO;
  
-     constexpr Color Them     = (Us == WHITE ? BLACK : WHITE);
+     constexpr Color Them     = ~Us;
      constexpr Direction Down = -pawn_push(Us);
      constexpr Bitboard SpaceMask =
        Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
@@@ -91,9 -82,9 +91,9 @@@ namespace 
    /// imbalance() calculates the imbalance by comparing the piece count of each
    /// piece type for both colors.
    template<Color Us>
 -  int imbalance(const int pieceCount[][PIECE_TYPE_NB]) {
 +  int imbalance(const Position& pos, const int pieceCount[][PIECE_TYPE_NB]) {
  
-     constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
+     constexpr Color Them = ~Us;
  
      int bonus = 0;
  
diff --cc src/movegen.cpp
@@@ -87,9 -52,10 +87,9 @@@ namespace 
    template<Color Us, GenType Type>
    ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList, Bitboard target) {
  
-     constexpr Color     Them     = (Us == WHITE ? BLACK      : WHITE);
+     constexpr Color     Them     = ~Us;
 -    constexpr Bitboard  TRank7BB = (Us == WHITE ? Rank7BB    : Rank2BB);
 -    constexpr Bitboard  TRank3BB = (Us == WHITE ? Rank3BB    : Rank6BB);
      constexpr Direction Up       = pawn_push(Us);
 +    constexpr Direction Down     = -pawn_push(Us);
      constexpr Direction UpRight  = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
      constexpr Direction UpLeft   = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
  
Simple merge
diff --cc src/pawns.cpp
@@@ -210,9 -187,9 +210,9 @@@ Entry* probe(const Position& pos) 
  template<Color Us>
  Score Entry::evaluate_shelter(const Position& pos, Square ksq) {
  
-   constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
+   constexpr Color Them = ~Us;
  
 -  Bitboard b = pos.pieces(PAWN) & ~forward_ranks_bb(Them, ksq);
 +  Bitboard b = pos.pieces(PAWN, SHOGI_PAWN) & ~forward_ranks_bb(Them, ksq);
    Bitboard ourPawns = b & pos.pieces(Us);
    Bitboard theirPawns = b & pos.pieces(Them);
  
@@@ -1164,12 -666,12 +1164,12 @@@ bool Position::gives_check(Move m) cons
    case CASTLING:
    {
        Square kfrom = from;
-       Square rfrom = to; // Castling is encoded as 'King captures the rook'
+       Square rfrom = to; // Castling is encoded as 'king captures the rook'
 -      Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1);
 -      Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1);
 +      Square kto = make_square(rfrom > kfrom ? castling_kingside_file() : castling_queenside_file(), castling_rank(sideToMove));
 +      Square rto = kto + (rfrom > kfrom ? WEST : EAST);
  
 -      return   (PseudoAttacks[ROOK][rto] & square<KING>(~sideToMove))
 -            && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
 +      return   (PseudoAttacks[sideToMove][type_of(piece_on(rfrom))][rto] & square<KING>(~sideToMove))
 +            && (attacks_bb(sideToMove, type_of(piece_on(rfrom)), rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square<KING>(~sideToMove));
    }
    default:
        assert(false);
diff --cc src/search.cpp
Simple merge
diff --cc src/uci.cpp
@@@ -118,10 -114,8 +118,10 @@@ namespace 
  
      limits.startTime = now(); // As early as possible!
  
 +    limits.banmoves = banmoves;
 +
      while (is >> token)
-         if (token == "searchmoves")
+         if (token == "searchmoves") // Needs to be the last command on the line
              while (is >> token)
                  limits.searchmoves.push_back(UCI::to_move(pos, token));