From: Fabian Fichter Date: Thu, 3 Sep 2020 19:12:25 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=542970efaa1878de10ee835c68450c1e5e8b90a3;p=fairystockfish.git Merge official-stockfish/master bench: 4777225 --- 542970efaa1878de10ee835c68450c1e5e8b90a3 diff --cc src/evaluate.cpp index fcecece,dc7134a..9904d7a --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -131,12 -126,9 +131,13 @@@ namespace S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260) }; + // KingProximity contains a penalty according to distance from king + constexpr Score KingProximity = S(2, 4); + constexpr Score EndgameKingProximity = S(0, 10); + // Assorted bonuses and penalties constexpr Score BishopPawns = S( 3, 7); + constexpr Score BishopOnKingRing = S( 24, 0); constexpr Score BishopXRayPawns = S( 4, 5); constexpr Score CorneredBishop = S( 50, 50); constexpr Score FlankAttacks = S( 8, 0); @@@ -319,42 -286,19 +320,46 @@@ if (b & kingRing[Them]) { kingAttackersCount[Us]++; - kingAttackersWeight[Us] += KingAttackWeights[Pt]; + kingAttackersWeight[Us] += KingAttackWeights[std::min(int(Pt), QUEEN + 1)]; kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]); } + else if (Pt == ROOK && (file_bb(s) & kingRing[Them])) score += RookOnKingRing; + else if (Pt == BISHOP && (attacks_bb(s, pos.pieces(PAWN)) & kingRing[Them])) + score += BishopOnKingRing; + + if (Pt > QUEEN) + b = (b & pos.pieces()) | (pos.moves_from(Us, Pt, s) & ~pos.pieces() & pos.board_bb()); + int mob = popcount(b & mobilityArea[Us]); - mobility[Us] += MobilityBonus[Pt - 2][mob]; + if (Pt <= QUEEN) + mobility[Us] += MobilityBonus[Pt - 2][mob]; + else + mobility[Us] += MaxMobility * (mob - 2) / (8 + mob); + + // Piece promotion bonus + if (pos.promoted_piece_type(Pt) != NO_PIECE_TYPE) + { + if (promotion_zone_bb(Us, pos.promotion_rank(), pos.max_rank()) & (b | s)) + score += make_score(PieceValue[MG][pos.promoted_piece_type(Pt)] - PieceValue[MG][Pt], + PieceValue[EG][pos.promoted_piece_type(Pt)] - PieceValue[EG][Pt]) / 10; + } + else if (pos.piece_demotion() && pos.unpromoted_piece_on(s)) + score -= make_score(PieceValue[MG][Pt] - PieceValue[MG][pos.unpromoted_piece_on(s)], + PieceValue[EG][Pt] - PieceValue[EG][pos.unpromoted_piece_on(s)]) / 4; + else if (pos.captures_to_hand() && pos.unpromoted_piece_on(s)) + score += make_score(PieceValue[MG][Pt] - PieceValue[MG][pos.unpromoted_piece_on(s)], + PieceValue[EG][Pt] - PieceValue[EG][pos.unpromoted_piece_on(s)]) / 8; + + // Penalty if the piece is far from the kings in drop variants + if ((pos.captures_to_hand() || pos.two_boards()) && pos.count(Them) && pos.count(Us)) + score -= KingProximity * distance(s, pos.square(Us)) * distance(s, pos.square(Them)); + + else if (pos.count(Us) && (Pt == FERS || Pt == SILVER)) + score -= EndgameKingProximity * (distance(s, pos.square(Us)) - 2); if (Pt == BISHOP || Pt == KNIGHT) { diff --cc src/movegen.cpp index 3d3082f,b57f41a..5cbc279 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@@ -265,65 -179,32 +265,64 @@@ namespace } - template - ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Color us, PieceType pt, - Bitboard target) { - template - ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Bitboard target) { ++ template ++ ExtMove* generate_moves(const Position& pos, ExtMove* moveList, PieceType pt, Bitboard target) { - static_assert(Pt != KING && Pt != PAWN, "Unsupported piece type in generate_moves()"); + assert(pt != KING && pt != PAWN); - const Square* pl = pos.squares(us, pt); - const Square* pl = pos.squares(Us); ++ const Square* pl = pos.squares(Us, pt); for (Square from = *pl; from != SQ_NONE; from = *++pl) { + // Avoid generating discovered checks twice - if (Checks && (pos.blockers_for_king(~us) & from)) ++ if (Checks && (pos.blockers_for_king(~Us) & from)) + continue; + - Bitboard b1 = ( (pos.attacks_from(us, pt, from) & pos.pieces()) - | (pos.moves_from(us, pt, from) & ~pos.pieces())) & target; ++ Bitboard b1 = ( (pos.attacks_from(Us, pt, from) & pos.pieces()) ++ | (pos.moves_from(Us, pt, from) & ~pos.pieces())) & target; + PieceType prom_pt = pos.promoted_piece_type(pt); - Bitboard b2 = prom_pt && (!pos.promotion_limit(prom_pt) || pos.promotion_limit(prom_pt) > pos.count(us, prom_pt)) ? b1 : Bitboard(0); ++ Bitboard b2 = prom_pt && (!pos.promotion_limit(prom_pt) || pos.promotion_limit(prom_pt) > pos.count(Us, prom_pt)) ? b1 : Bitboard(0); + Bitboard b3 = pos.piece_demotion() && pos.is_promoted(from) ? b1 : Bitboard(0); + if (Checks) { - if ( (Pt == BISHOP || Pt == ROOK || Pt == QUEEN) - && !(attacks_bb(from) & target & pos.check_squares(Pt))) - continue; + b1 &= pos.check_squares(pt); + if (b2) + b2 &= pos.check_squares(pos.promoted_piece_type(pt)); + if (b3) + b3 &= pos.check_squares(type_of(pos.unpromoted_piece_on(from))); + } - if (pos.blockers_for_king(~Us) & from) - continue; + // Restrict target squares considering promotion zone + if (b2 | b3) + { - Bitboard promotion_zone = promotion_zone_bb(us, pos.promotion_rank(), pos.max_rank()); ++ Bitboard promotion_zone = promotion_zone_bb(Us, pos.promotion_rank(), pos.max_rank()); + if (pos.mandatory_piece_promotion()) + b1 &= (promotion_zone & from ? Bitboard(0) : ~promotion_zone) | (pos.piece_promotion_on_capture() ? ~pos.pieces() : Bitboard(0)); + // Exclude quiet promotions/demotions + if (pos.piece_promotion_on_capture()) + { + b2 &= pos.pieces(); + b3 &= pos.pieces(); + } + // Consider promotions/demotions into promotion zone + if (!(promotion_zone & from)) + { + b2 &= promotion_zone; + b3 &= promotion_zone; + } } - Bitboard b = attacks_bb(from, pos.pieces()) & target; + while (b1) - moveList = make_move_and_gating(pos, moveList, us, from, pop_lsb(&b1)); ++ moveList = make_move_and_gating(pos, moveList, Us, from, pop_lsb(&b1)); - if (Checks) - b &= pos.check_squares(Pt); + // Shogi-style piece promotions + while (b2) + *moveList++ = make(from, pop_lsb(&b2)); - while (b) - *moveList++ = make_move(from, pop_lsb(&b)); + // Piece demotions + while (b3) + *moveList++ = make(from, pop_lsb(&b3)); } return moveList; @@@ -364,28 -237,19 +363,28 @@@ default: static_assert(true, "Unsupported type in generate_all()"); } + target &= pos.board_bb(); moveList = generate_pawn_moves(pos, moveList, target); - moveList = generate_moves(pos, moveList, target); - moveList = generate_moves(pos, moveList, target); - moveList = generate_moves(pos, moveList, target); - moveList = generate_moves(pos, moveList, target); - - if (Type != QUIET_CHECKS && Type != EVASIONS) + for (PieceType pt : pos.piece_types()) + if (pt != PAWN && pt != KING) - moveList = generate_moves(pos, moveList, Us, pt, target); ++ moveList = generate_moves(pos, moveList, pt, target); + // generate drops + if (pos.piece_drops() && Type != CAPTURES && pos.count_in_hand(Us, ALL_PIECES)) + for (PieceType pt : pos.piece_types()) + moveList = generate_drops(pos, moveList, pt, target & ~pos.pieces(~Us)); + + if (Type != QUIET_CHECKS && Type != EVASIONS && pos.count(Us)) { Square ksq = pos.square(Us); - Bitboard b = attacks_bb(ksq) & target; + Bitboard b = ( (pos.attacks_from(Us, KING, ksq) & pos.pieces()) + | (pos.moves_from(Us, KING, ksq) & ~pos.pieces())) & target; while (b) - *moveList++ = make_move(ksq, pop_lsb(&b)); + moveList = make_move_and_gating(pos, moveList, Us, ksq, pop_lsb(&b)); + + // Passing move by king + if (pos.pass()) + *moveList++ = make(ksq, ksq); if ((Type != CAPTURES) && pos.can_castle(Us & ANY_CASTLING)) for(CastlingRights cr : { Us & KING_SIDE, Us & QUEEN_SIDE } ) diff --cc src/movepick.cpp index 60b906d,78102c5..f0226ee --- a/src/movepick.cpp +++ b/src/movepick.cpp @@@ -110,11 -106,11 +110,11 @@@ void MovePicker::score() else if (Type == QUIETS) m.value = (*mainHistory)[pos.side_to_move()][from_to(m)] - + 2 * (*continuationHistory[0])[pos.moved_piece(m)][to_sq(m)] - + 2 * (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)] - + 2 * (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)] - + (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)] + + 2 * (*continuationHistory[0])[history_slot(pos.moved_piece(m))][to_sq(m)] + + 2 * (*continuationHistory[1])[history_slot(pos.moved_piece(m))][to_sq(m)] + + 2 * (*continuationHistory[3])[history_slot(pos.moved_piece(m))][to_sq(m)] + + (*continuationHistory[5])[history_slot(pos.moved_piece(m))][to_sq(m)] - + (ply < MAX_LPH ? 4 * (*lowPlyHistory)[ply][from_to(m)] : 0); + + (ply < MAX_LPH ? std::min(4, depth / 3) * (*lowPlyHistory)[ply][from_to(m)] : 0); else // Type == EVASIONS { diff --cc src/pawns.cpp index 2079912,c1119a4..de61974 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@@ -148,13 -145,13 +148,13 @@@ namespace else if (!neighbours) { - score -= Isolated * (1 + 2 * pos.must_capture()) - + WeakUnopposed * !opposed; - - if ( (ourPawns & forward_file_bb(Them, s)) - && popcount(opposed) == 1 + if ( opposed + && (ourPawns & forward_file_bb(Them, s)) && !(theirPawns & adjacent_files_bb(s))) - score -= Doubled; + score -= Doubled * (1 + 2 * pos.must_capture()); + else - score -= Isolated ++ score -= Isolated * (1 + 2 * pos.must_capture()) + + WeakUnopposed * !opposed; } else if (backward) diff --cc src/search.cpp index d8cb9e9,efa7b9c..2709092 --- a/src/search.cpp +++ b/src/search.cpp @@@ -586,37 -556,11 +586,39 @@@ void Thread::search() } double bestMoveInstability = 1 + totBestMoveChanges / Threads.size(); + double totalTime = rootMoves.size() == 1 ? 0 : + Time.optimum() * fallingEval * reduction * bestMoveInstability; + + if (completedDepth >= 8 && rootPos.two_boards() && Options["Protocol"] == "xboard") + { + if (Limits.time[us]) + Partner.ptell("time " + std::to_string((Limits.time[us] - Time.elapsed()) / 10)); + if (Limits.time[~us]) + Partner.ptell("otim " + std::to_string(Limits.time[~us] / 10)); + if (!Partner.weDead && bestValue <= VALUE_MATED_IN_MAX_PLY) + { + Partner.ptell("dead"); + Partner.weDead = true; + } + else if (Partner.weDead && bestValue > VALUE_MATED_IN_MAX_PLY) + { + Partner.ptell("x"); + Partner.weDead = false; + } + else if (!Partner.weWin && bestValue >= VALUE_MATE_IN_MAX_PLY && Limits.time[~us] < Partner.time * 10) + { + Partner.ptell("sit"); + Partner.weWin = true; + } + else if (Partner.weWin && (bestValue < VALUE_MATE_IN_MAX_PLY || Limits.time[~us] > Partner.time * 10)) + { + Partner.ptell("x"); + Partner.weWin = false; + } + } + - // Stop the search if we have only one legal move, or if available time elapsed - if ( rootMoves.size() == 1 - || Time.elapsed() > Time.optimum() * fallingEval * reduction * bestMoveInstability) + // Stop the search if we have exceeded the totalTime, at least 1ms search. + if (Time.elapsed() > totalTime) { // If we are allowed to ponder do not stop the search now but // keep pondering until the GUI sends "ponderhit" or "stop".