From: Fabian Fichter Date: Sun, 20 Sep 2020 11:55:24 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=5601109e6c4df9c63588d63d64e6149e3b5e7461;p=fairystockfish.git Merge official-stockfish/master No functional change. --- 5601109e6c4df9c63588d63d64e6149e3b5e7461 diff --cc src/bitboard.h index 088edcd,afeb40e..8167bb5 --- a/src/bitboard.h +++ b/src/bitboard.h @@@ -199,11 -138,11 +199,11 @@@ constexpr bool opposite_colors(Square s /// rank_bb() and file_bb() return a bitboard representing all the squares on /// the given file or rank. - inline Bitboard rank_bb(Rank r) { + constexpr Bitboard rank_bb(Rank r) { - return Rank1BB << (8 * r); + return Rank1BB << (FILE_NB * r); } - inline Bitboard rank_bb(Square s) { + constexpr Bitboard rank_bb(Square s) { return rank_bb(rank_of(s)); } @@@ -312,23 -229,9 +312,23 @@@ inline Bitboard between_bb(Square s1, S /// 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. - inline Bitboard forward_ranks_bb(Color c, Square s) { + constexpr Bitboard forward_ranks_bb(Color c, Square s) { - return c == WHITE ? ~Rank1BB << 8 * relative_rank(WHITE, s) - : ~Rank8BB >> 8 * relative_rank(BLACK, s); + return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * relative_rank(WHITE, s, RANK_MAX) + : (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * relative_rank(BLACK, s, RANK_MAX); +} + - inline Bitboard forward_ranks_bb(Color c, Rank r) { ++constexpr Bitboard forward_ranks_bb(Color c, Rank r) { + return c == WHITE ? (AllSquares ^ Rank1BB) << FILE_NB * (r - RANK_1) + : (AllSquares ^ rank_bb(RANK_MAX)) >> FILE_NB * (RANK_MAX - r); +} + + +/// promotion_zone_bb() returns a bitboard representing the squares on all the ranks +/// in front of and on the given relative rank, from the point of view of the given color. +/// For instance, promotion_zone_bb(BLACK, RANK_7) will return the 16 squares on ranks 1 and 2. + +inline Bitboard promotion_zone_bb(Color c, Rank r, Rank maxRank) { + return forward_ranks_bb(c, relative_rank(c, r, maxRank)) | rank_bb(relative_rank(c, r, maxRank)); } diff --cc src/evaluate.cpp index 3fe0e33,6f2dd69..2058a95 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -951,147 -719,9 +951,147 @@@ namespace } + // Evaluation::variant() computes variant-specific evaluation bonuses for a given side. + + template template + Score Evaluation::variant() const { + + constexpr Color Them = ~Us; + constexpr Direction Down = pawn_push(Them); + + Score score = SCORE_ZERO; + + // Capture the flag + if (pos.capture_the_flag(Us)) + { + PieceType ptCtf = pos.capture_the_flag_piece(); + Bitboard ctfPieces = pos.pieces(Us, ptCtf); + Bitboard ctfTargets = pos.capture_the_flag(Us) & pos.board_bb(); + Bitboard onHold = 0; + Bitboard onHold2 = 0; + Bitboard processed = 0; + Bitboard blocked = pos.pieces(Us, PAWN) | attackedBy[Them][ALL_PIECES]; + Bitboard doubleBlocked = attackedBy2[Them] + | (pos.pieces(Us, PAWN) & (shift(pos.pieces()) | attackedBy[Them][ALL_PIECES])) + | (pos.pieces(Them) & pe->pawn_attacks(Them)) + | (pawn_attacks_bb(pos.pieces(Them, PAWN) & pe->pawn_attacks(Them))); + Bitboard inaccessible = pos.pieces(Us, PAWN) & shift(pos.pieces(Them, PAWN)); + // Traverse all paths of the CTF pieces to the CTF targets. + // Put squares that are attacked or occupied on hold for one iteration. + for (int dist = 0; (ctfPieces || onHold || onHold2) && (ctfTargets & ~processed); dist++) + { + int wins = popcount(ctfTargets & ctfPieces); + if (wins) + score += make_score(4000, 4000) * wins / (wins + dist * dist); + Bitboard current = ctfPieces & ~ctfTargets; + processed |= ctfPieces; + ctfPieces = onHold & ~processed; + onHold = onHold2 & ~processed; + onHold2 = 0; + while (current) + { + Square s = pop_lsb(¤t); + Bitboard attacks = ( (PseudoAttacks[Us][ptCtf][s] & pos.pieces()) + | (PseudoMoves[Us][ptCtf][s] & ~pos.pieces())) & ~processed & pos.board_bb(); + ctfPieces |= attacks & ~blocked; + onHold |= attacks & ~doubleBlocked; + onHold2 |= attacks & ~inaccessible; + } + } + } + + // nCheck + if (pos.check_counting()) + { + int remainingChecks = pos.checks_remaining(Us); + assert(remainingChecks > 0); + score += make_score(3600, 1000) / (remainingChecks * remainingChecks); + } + + // Extinction + if (pos.extinction_value() != VALUE_NONE) + { + for (PieceType pt : pos.extinction_piece_types()) + if (pt != ALL_PIECES) + { + int denom = std::max(pos.count(Us, pt) - pos.extinction_piece_count(), 1); + if (pos.count(Them, pt) >= pos.extinction_opponent_piece_count() || pos.two_boards()) + score += make_score(1000000 / (500 + PieceValue[MG][pt]), + 1000000 / (500 + PieceValue[EG][pt])) / (denom * denom) + * (pos.extinction_value() / VALUE_MATE); + } + else if (pos.extinction_value() == VALUE_MATE) + score += make_score(pos.non_pawn_material(Us), pos.non_pawn_material(Us)) / pos.count(Us); + } + + // Connect-n + if (pos.connect_n() > 0) + { + for (Direction d : {NORTH, NORTH_EAST, EAST, SOUTH_EAST}) + { + // Find sufficiently large gaps + Bitboard b = pos.board_bb() & ~pos.pieces(Them); + for (int i = 1; i < pos.connect_n(); i++) + b &= shift(d, b); + // Count number of pieces per gap + while (b) + { + Square s = pop_lsb(&b); + int c = 0; + for (int j = 0; j < pos.connect_n(); j++) + if (pos.pieces(Us) & (s - j * d)) + c++; + score += make_score(200, 200) * c / (pos.connect_n() - c) / (pos.connect_n() - c); + } + } + } + + // Potential piece flips + if (pos.flip_enclosed_pieces()) + { + // Stable pieces + if (pos.flip_enclosed_pieces() == REVERSI) + { + Bitboard edges = (FileABB | file_bb(pos.max_file()) | Rank1BB | rank_bb(pos.max_rank())) & pos.board_bb(); + Bitboard edgePieces = pos.pieces(Us) & edges; + while (edgePieces) + { + Bitboard connectedEdge = attacks_bb(Us, ROOK, pop_lsb(&edgePieces), ~(pos.pieces(Us) & edges)) & edges; + if (!more_than_one(connectedEdge & ~pos.pieces(Us))) + score += make_score(300, 300); + else if (!(connectedEdge & ~pos.pieces())) + score += make_score(200, 200); + } + } + + // Unstable + Bitboard unstable = 0; + Bitboard drops = pos.drop_region(Them, IMMOBILE_PIECE); + while (drops) + { + Square s = pop_lsb(&drops); + if (pos.flip_enclosed_pieces() == REVERSI) + { + Bitboard b = attacks_bb(Them, QUEEN, s, ~pos.pieces(Us)) & ~PseudoAttacks[Them][KING][s] & pos.pieces(Them); + while(b) + unstable |= between_bb(s, pop_lsb(&b)); + } + else + unstable |= PseudoAttacks[Them][KING][s] & pos.pieces(Us); + } + score -= make_score(200, 200) * popcount(unstable); + } + + if (T) + Trace::add(VARIANT, Us, score); + + return score; + } + + - // Evaluation::winnable() adjusts the mg and eg score components based on the - // known attacking/defending status of the players. A single value is derived - // by interpolation from the mg and eg values and returned. + // Evaluation::winnable() adjusts the midgame and endgame score components, based on + // the known attacking/defending status of the players. The final value is derived + // by interpolation from the midgame and endgame values. template Value Evaluation::winnable(Score score) const { @@@ -1142,8 -764,8 +1142,8 @@@ Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK; int sf = me->scale_factor(pos, strongSide); - // If scale is not already specific, scale down the endgame via general heuristics + // If scale factor is not already specific, scale down via general heuristics - if (sf == SCALE_FACTOR_NORMAL) + if (sf == SCALE_FACTOR_NORMAL && !pos.captures_to_hand()) { if (pos.opposite_bishops()) { diff --cc src/search.cpp index 9fd9dac,720a910..71ef344 --- a/src/search.cpp +++ b/src/search.cpp @@@ -283,12 -261,12 +283,12 @@@ void MainThread::search() if (Limits.npmsec) Time.availableNodes += Limits.inc[us] - Threads.nodes_searched(); - Thread* bestThread = this; + bestThread = this; - if (int(Options["MultiPV"]) == 1 && - !Limits.depth && - !(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"])) && - rootMoves[0].pv[0] != MOVE_NONE) + if ( int(Options["MultiPV"]) == 1 + && !Limits.depth + && !(Skill(Options["Skill Level"]).enabled() || int(Options["UCI_LimitStrength"])) + && rootMoves[0].pv[0] != MOVE_NONE) bestThread = Threads.get_best_thread(); bestPreviousScore = bestThread->rootMoves[0].score;