From: Fabian Fichter Date: Tue, 18 May 2021 13:34:32 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=4f9ea6760325c91999349b3a5d1fc532f1135afe;p=fairystockfish.git Merge official-stockfish/master bench: 5269468 --- 4f9ea6760325c91999349b3a5d1fc532f1135afe diff --cc src/bitboard.cpp index c562ab8,8146ce9..eb7c628 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@@ -203,18 -55,18 +203,18 @@@ inline Bitboard safe_destination(Squar /// Bitboards::pretty() returns an ASCII representation of a bitboard suitable /// to be printed to standard output. Useful for debugging. - const std::string Bitboards::pretty(Bitboard b) { + std::string Bitboards::pretty(Bitboard b) { - std::string s = "+---+---+---+---+---+---+---+---+\n"; + std::string s = "+---+---+---+---+---+---+---+---+---+---+---+---+\n"; - for (Rank r = RANK_8; r >= RANK_1; --r) + for (Rank r = RANK_MAX; r >= RANK_1; --r) { - for (File f = FILE_A; f <= FILE_H; ++f) + for (File f = FILE_A; f <= FILE_MAX; ++f) s += b & make_square(f, r) ? "| X " : "| "; - s += "| " + std::to_string(1 + r) + "\n+---+---+---+---+---+---+---+---+\n"; + s += "| " + std::to_string(1 + r) + "\n+---+---+---+---+---+---+---+---+---+---+---+---+\n"; } - s += " a b c d e f g h\n"; + s += " a b c d e f g h i j k\n"; return s; } diff --cc src/bitboard.h index 2ac5f5a,c9555b6..5c177b8 --- a/src/bitboard.h +++ b/src/bitboard.h @@@ -32,9 -32,8 +32,9 @@@ bool probe(Square wksq, Square wpsq, Sq namespace Bitboards { +void init_pieces(); void init(); - const std::string pretty(Bitboard b); + std::string pretty(Bitboard b); } diff --cc src/misc.cpp index ec4dd94,fe92014..5aac113 --- a/src/misc.cpp +++ b/src/misc.cpp @@@ -138,7 -138,7 +138,7 @@@ public /// the program was compiled) or "Stockfish ", depending on whether /// Version is empty. - const string engine_info(bool to_uci, bool to_xboard) { -string engine_info(bool to_uci) { ++string engine_info(bool to_uci, bool to_xboard) { const string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"); string month, day, year; diff --cc src/misc.h index 1cdd52a,7eb75bc..61fa2b1 --- a/src/misc.h +++ b/src/misc.h @@@ -28,8 -28,8 +28,8 @@@ #include "types.h" - const std::string engine_info(bool to_uci = false, bool to_xboard = false); - const std::string compiler_info(); -std::string engine_info(bool to_uci = false); ++std::string engine_info(bool to_uci = false, bool to_xboard = false); + std::string compiler_info(); void prefetch(void* addr); void start_logger(const std::string& fname); void* std_aligned_alloc(size_t alignment, size_t size); diff --cc src/position.cpp index dbc3a65,8f9b7ee..6c71c68 --- a/src/position.cpp +++ b/src/position.cpp @@@ -633,7 -408,7 +633,7 @@@ Position& Position::set(const string& c /// Position::fen() returns a FEN representation of the position. In case of /// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function. - const string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings) const { -string Position::fen() const { ++string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings) const { int emptyCnt; std::ostringstream ss; diff --cc src/position.h index a6307e8,e980375..f072393 --- a/src/position.h +++ b/src/position.h @@@ -106,101 -85,12 +106,101 @@@ public Position& operator=(const Position&) = delete; // FEN string input/output - Position& set(const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th); + Position& set(const Variant* v, const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th, bool sfen = false); Position& set(const std::string& code, Color c, StateInfo* si); - const std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-") const; - std::string fen() const; ++ std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-") const; + + // Variant rule properties + const Variant* variant() const; + Rank max_rank() const; + File max_file() const; + bool two_boards() const; + Bitboard board_bb() const; + Bitboard board_bb(Color c, PieceType pt) const; + const std::set& piece_types() const; + const std::string& piece_to_char() const; + const std::string& piece_to_char_synonyms() const; + Rank promotion_rank() const; + const std::set >& promotion_piece_types() const; + bool sittuyin_promotion() const; + int promotion_limit(PieceType pt) const; + PieceType promoted_piece_type(PieceType pt) const; + bool piece_promotion_on_capture() const; + bool mandatory_pawn_promotion() const; + bool mandatory_piece_promotion() const; + bool piece_demotion() const; + bool blast_on_capture() const; + bool endgame_eval() const; + bool double_step_enabled() const; + Rank double_step_rank_max() const; + Rank double_step_rank_min() const; + bool castling_enabled() const; + bool castling_dropped_piece() const; + File castling_kingside_file() const; + File castling_queenside_file() const; + Rank castling_rank(Color c) const; + File castling_king_file() const; + PieceType castling_king_piece() const; + PieceType castling_rook_piece() const; + PieceType king_type() const; + PieceType nnue_king() const; + bool checking_permitted() const; + bool drop_checks() const; + bool must_capture() const; + bool has_capture() const; + bool must_drop() const; + bool piece_drops() const; + bool drop_loop() const; + bool captures_to_hand() const; + bool first_rank_pawn_drops() const; + bool drop_on_top() const; + EnclosingRule enclosing_drop() const; + Bitboard drop_region(Color c) const; + Bitboard drop_region(Color c, PieceType pt) const; + bool sittuyin_rook_drop() const; + bool drop_opposite_colored_bishop() const; + bool drop_promoted() const; + PieceType drop_no_doubled() const; + bool immobility_illegal() const; + bool gating() const; + bool arrow_gating() const; + bool seirawan_gating() const; + bool cambodian_moves() const; + Bitboard diagonal_lines() const; + bool pass() const; + bool pass_on_stalemate() const; + Bitboard promoted_soldiers(Color c) const; + bool makpong() const; + EnclosingRule flip_enclosed_pieces() const; + // winning conditions + int n_move_rule() const; + int n_fold_rule() const; + Value stalemate_value(int ply = 0) const; + Value checkmate_value(int ply = 0) const; + Value extinction_value(int ply = 0) const; + bool extinction_claim() const; + const std::set& extinction_piece_types() const; + bool extinction_single_piece() const; + int extinction_piece_count() const; + int extinction_opponent_piece_count() const; + PieceType capture_the_flag_piece() const; + Bitboard capture_the_flag(Color c) const; + bool flag_move() const; + bool check_counting() const; + int connect_n() const; + CheckCount checks_remaining(Color c) const; + MaterialCounting material_counting() const; + CountingRule counting_rule() const; + + // Variant-specific properties + int count_in_hand(PieceType pt) const; + int count_in_hand(Color c, PieceType pt) const; + int count_with_hand(Color c, PieceType pt) const; + bool bikjang() const; + bool allow_virtual_drop(Color c, PieceType pt) const; // Position representation - Bitboard pieces(PieceType pt) const; + Bitboard pieces(PieceType pt = ALL_PIECES) const; Bitboard pieces(PieceType pt1, PieceType pt2) const; Bitboard pieces(Color c) const; Bitboard pieces(Color c, PieceType pt) const; diff --cc src/search.cpp index 7b68b1a,b3bd2f0..2f3018d --- a/src/search.cpp +++ b/src/search.cpp @@@ -972,14 -840,12 +973,14 @@@ namespace // Step 8. Null move search with verification search (~40 Elo) if ( !PvNode && (ss-1)->currentMove != MOVE_NULL - && (ss-1)->statScore < 22661 + && (ss-1)->statScore < 24185 && eval >= beta && eval >= ss->staticEval - && ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159 + && ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159 + 200 * (!pos.double_step_enabled() && pos.piece_to_char()[PAWN] != ' ') && !excludedMove && pos.non_pawn_material(us) + && pos.count(~us) != pos.count(~us) + && !pos.flip_enclosed_pieces() && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor)) { assert(eval - beta >= 0); @@@ -1171,9 -1053,9 +1188,9 @@@ moves_loop: // When in check, search st // Calculate new depth for this move newDepth = depth - 1; - // Step 12. Pruning at shallow depth (~200 Elo) + // Step 13. Pruning at shallow depth (~200 Elo) if ( !rootNode - && pos.non_pawn_material(us) + && (pos.non_pawn_material(us) || pos.count(us) == pos.count(us)) && bestValue > VALUE_TB_LOSS_IN_MAX_PLY) { // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold @@@ -1210,12 -1088,11 +1227,12 @@@ // Futility pruning: parent node (~5 Elo) if ( lmrDepth < 7 && !ss->inCheck - && ss->staticEval + 174 + 157 * lmrDepth <= alpha - && (*contHist[0])[movedPiece][to_sq(move)] - + (*contHist[1])[movedPiece][to_sq(move)] - + (*contHist[3])[movedPiece][to_sq(move)] - + (*contHist[5])[movedPiece][to_sq(move)] / 3 < 28255) + && !pos.extinction_single_piece() + && ss->staticEval + (174 + 157 * lmrDepth) * (1 + pos.check_counting()) <= alpha + && (*contHist[0])[history_slot(movedPiece)][to_sq(move)] + + (*contHist[1])[history_slot(movedPiece)][to_sq(move)] + + (*contHist[3])[history_slot(movedPiece)][to_sq(move)] - + (*contHist[5])[history_slot(movedPiece)][to_sq(move)] / 3 < 26237) ++ + (*contHist[5])[history_slot(movedPiece)][to_sq(move)] / 3 < 28255) continue; // Prune moves with negative SEE (~20 Elo) @@@ -1297,17 -1170,20 +1314,21 @@@ ss->currentMove = move; ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck] [captureOrPromotion] - [movedPiece] + [history_slot(movedPiece)] [to_sq(move)]; - // Step 14. Make the move + // Step 15. Make the move pos.do_move(move, st, givesCheck); - // Step 15. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be - // re-searched at full depth. + (ss+1)->distanceFromPv = ss->distanceFromPv + moveCount - 1; + + // Step 16. Late moves reduction / extension (LMR, ~200 Elo) + // We use various heuristics for the sons of a node after the first son has + // been searched. In general we would like to reduce them, but there are many + // cases where we extend a son if it has good chances to be "interesting". if ( depth >= 3 && moveCount > 1 + 2 * rootNode + && !(pos.must_capture() && pos.has_capture()) && ( !captureOrPromotion || moveCountPruning || ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha @@@ -1374,10 -1250,10 +1395,10 @@@ r -= 2 + ss->ttPv - (type_of(movedPiece) == PAWN); ss->statScore = thisThread->mainHistory[us][from_to(move)] - + (*contHist[0])[movedPiece][to_sq(move)] - + (*contHist[1])[movedPiece][to_sq(move)] - + (*contHist[3])[movedPiece][to_sq(move)] + + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] + + (*contHist[1])[history_slot(movedPiece)][to_sq(move)] + + (*contHist[3])[history_slot(movedPiece)][to_sq(move)] - - 5337; + - 4741; // Decrease/increase reduction by comparing opponent's stat score (~10 Elo) if (ss->statScore >= -89 && (ss-1)->statScore < -116) @@@ -1387,16 -1263,19 +1408,19 @@@ r++; // Decrease/increase reduction for moves with a good/bad history (~30 Elo) - // If we are not in check use statScore, if we are in check - // use sum of main history and first continuation history with an offset + // If we are not in check use statScore, but if we are in check we use + // the sum of main history and first continuation history with an offset. if (ss->inCheck) r -= (thisThread->mainHistory[us][from_to(move)] - + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] - 4341) / 16384; - + (*contHist[0])[movedPiece][to_sq(move)] - 3833) / 16384; ++ + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] - 3833) / 16384; else - r -= ss->statScore / (14382 - 4434 * pos.captures_to_hand()); - r -= ss->statScore / 14790; ++ r -= ss->statScore / (14790 - 4434 * pos.captures_to_hand()); } - Depth d = std::clamp(newDepth - r, 1, newDepth); + // In general we want to cap the LMR depth search at newDepth. But for nodes + // close to the principal variation the cap is at (newDepth + 1), which will + // allow these nodes to be searched deeper than the pv (up to 4 plies deeper). + Depth d = std::clamp(newDepth - r, 1, newDepth + ((ss+1)->distanceFromPv <= 4)); value = -search(pos, ss+1, -(alpha+1), -alpha, d, true);