From: Fabian Fichter Date: Sat, 30 Mar 2019 13:32:34 +0000 (+0100) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=8ea3375d140857eade269fd6ec35680aa1b91b14;p=fairystockfish.git Merge official-stockfish/master No functional change. --- 8ea3375d140857eade269fd6ec35680aa1b91b14 diff --cc src/bitboard.h index 568f761,cf52b39..9614d33 --- a/src/bitboard.h +++ b/src/bitboard.h @@@ -203,17 -153,7 +203,17 @@@ inline Bitboard file_bb(Square s) } +/// make_bitboard() returns a bitboard from a list of squares + +constexpr Bitboard make_bitboard() { return 0; } + +template +constexpr Bitboard make_bitboard(Square s, Squares... squares) { + return (Bitboard(1) << s) | make_bitboard(squares...); +} + + - /// shift() moves a bitboard one step along direction D (mainly for pawns) + /// shift() moves a bitboard one step along direction D template constexpr Bitboard shift(Bitboard b) { diff --cc src/evaluate.cpp index ffce75c,fce0835..9dba7be --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -157,13 -151,10 +157,13 @@@ namespace S(-30,-14), S(-9, -8), S( 0, 9), S( -1, 7) }; + // KingProximity contains a penalty according to distance from king + constexpr Score KingProximity = S(2, 2); + // Assorted bonuses and penalties constexpr Score BishopPawns = S( 3, 7); - constexpr Score CloseEnemies = S( 8, 0); constexpr Score CorneredBishop = S( 50, 50); + constexpr Score FlankAttacks = S( 8, 0); constexpr Score Hanging = S( 69, 36); constexpr Score KingProtector = S( 7, 8); constexpr Score KnightOnQueen = S( 16, 12); @@@ -254,42 -243,39 +254,47 @@@ constexpr Color Them = (Us == WHITE ? BLACK : WHITE); constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH); constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH); - 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(Us); ++ const Square ksq = pos.count(Us) ? pos.square(Us) : SQ_NONE; + // Find our pawns that are blocked or on the first two ranks Bitboard b = pos.pieces(Us, PAWN) & (shift(pos.pieces()) | LowRanks); - // Squares occupied by those pawns, by our king or queen, or controlled by enemy pawns - // are excluded from the mobility area. + // Squares occupied by those pawns, by our king or queen or controlled by + // enemy pawns are excluded from the mobility area. - mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them)); + if (pos.must_capture()) + mobilityArea[Us] = AllSquares; + else + mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them) | shift(pos.pieces(Them, SHOGI_PAWN))); - // Initialise attackedBy bitboards for kings and pawns - attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, pos.square(Us)) : 0; - attackedBy[Us][PAWN] = pe->pawn_attacks(Us); + // Initialize attackedBy[] for king and pawns - attackedBy[Us][KING] = pos.attacks_from(ksq); ++ attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, ksq) : 0; + attackedBy[Us][PAWN] = pe->pawn_attacks(Us); - attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN]; - attackedBy2[Us] = attackedBy[Us][KING] & attackedBy[Us][PAWN]; + attackedBy[Us][SHOGI_PAWN] = shift(pos.pieces(Us, SHOGI_PAWN)); + attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN]; + attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN]) + | (attackedBy[Us][KING] & attackedBy[Us][SHOGI_PAWN]) + | (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN]); // Init our king safety tables kingRing[Us] = attackedBy[Us][KING]; - if (pos.count(Us) && relative_rank(Us, pos.square(Us), pos.max_rank()) == RANK_1) - if (relative_rank(Us, ksq) == RANK_1) ++ if (pos.count(Us) && relative_rank(Us, ksq) == RANK_1) kingRing[Us] |= shift(kingRing[Us]); - if (pos.count(Us) && file_of(pos.square(Us)) == pos.max_file()) - if (file_of(ksq) == FILE_H) ++ if (pos.count(Us) && file_of(ksq) == pos.max_file()) kingRing[Us] |= shift(kingRing[Us]); - else if (pos.count(Us) && file_of(pos.square(Us)) == FILE_A) - else if (file_of(ksq) == FILE_A) ++ else if (pos.count(Us) && file_of(ksq) == FILE_A) kingRing[Us] |= shift(kingRing[Us]); kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them)); - kingRing[Us] &= ~double_pawn_attacks_bb(pos.pieces(Us, PAWN)); kingAttacksCount[Them] = kingAttackersWeight[Them] = 0; + + // Remove from kingRing[] the squares defended by two pawns + kingRing[Us] &= ~pawn_double_attacks_bb(pos.pieces(Us, PAWN)); ++ + kingRing[Us] &= pos.board_bb(); } @@@ -301,10 -287,9 +306,9 @@@ constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH); constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB : Rank5BB | Rank4BB | Rank3BB); - const Square* pl = pos.squares(Us); + const Square* pl = pos.squares(Us, Pt); Bitboard b, bb; - Square s; Score score = SCORE_ZERO; attackedBy[Us][Pt] = 0; @@@ -465,31 -404,16 +469,19 @@@ Score Evaluation::king() const { constexpr Color Them = (Us == WHITE ? BLACK : WHITE); - 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 = AllSquares ^ forward_ranks_bb(Us, r); + + if (!pos.count(Us) || !pos.checking_permitted()) + return SCORE_ZERO; - Bitboard weak, b, b1, b2, safe, unsafeChecks = 0; ++ Bitboard weak, b, b1, b2, safe, QueenCheck, unsafeChecks = 0; + int kingDanger = 0; const Square ksq = pos.square(Us); - Bitboard kingFlank, weak, b, b1, b2, safe, unsafeChecks, QueenCheck; - // King shelter and enemy pawns storm + // Init the score with king shelter and enemy pawns storm Score score = pe->king_safety(pos); - // Find the squares that opponent attacks in our king flank, and the squares - // which are attacked twice in that flank but not defended by our pawns. - File f = std::max(std::min(file_of(ksq), File(pos.max_file() - 1)), FILE_B); - kingFlank = pos.max_file() == FILE_H ? KingFlank[file_of(ksq)] : file_bb(f) | adjacent_files_bb(f); - b1 = attackedBy[Them][ALL_PIECES] & kingFlank & Camp; - b2 = b1 & attackedBy2[Them]; - - int tropism = popcount(b1) + popcount(b2); - - // Main king safety evaluation - int kingDanger = 0; - unsafeChecks = 0; - // Attacked squares defended at most once by our queen or king weak = attackedBy[Them][ALL_PIECES] & ~attackedBy2[Us] @@@ -561,31 -471,34 +553,41 @@@ // the square is in the attacker's mobility area. unsafeChecks &= mobilityArea[Them]; ++ File f = std::max(std::min(file_of(ksq), File(pos.max_file() - 1)), FILE_B); ++ Bitboard kingFlank = pos.max_file() == FILE_H ? KingFlank[file_of(ksq)] : file_bb(f) | adjacent_files_bb(f); ++ + // Find the squares that opponent attacks in our king flank, and the squares + // which are attacked twice in that flank. - b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp; ++ b1 = attackedBy[Them][ALL_PIECES] & kingFlank & Camp; + b2 = b1 & attackedBy2[Them]; + + int kingFlankAttacks = popcount(b1) + popcount(b2); + kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] - + 69 * kingAttacksCount[Them] - + 185 * popcount(kingRing[Us] & weak) + + 69 * kingAttacksCount[Them] * (1 + 2 * !!pos.max_check_count()) + + 185 * popcount(kingRing[Us] & weak) * (1 + pos.captures_to_hand() + !!pos.max_check_count()) - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) + 150 * popcount(pos.blockers_for_king(Us) | unsafeChecks) - + 5 * tropism * tropism / 16 - - 873 * !pos.count(Them) + - 873 * !(pos.count(Them) || pos.captures_to_hand()) / (1 + !!pos.max_check_count()) - 6 * mg_value(score) / 8 + mg_value(mobility[Them] - mobility[Us]) + + 5 * kingFlankAttacks * kingFlankAttacks / 16 - 25; // Transform the kingDanger units into a Score, and subtract it from the evaluation if (kingDanger > 0) - score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16); + score -= make_score(std::min(kingDanger * kingDanger / 4096, 3000), kingDanger / 16); // Penalty when our king is on a pawnless flank - if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)])) + if (!(pos.pieces(PAWN) & kingFlank)) score -= PawnlessFlank; - // Penalty if king flank is under attack, potentially moving toward the king - score -= FlankAttacks * kingFlankAttacks; + // King tropism bonus, to anticipate slow motion attacks on our king - score -= CloseEnemies * tropism * (1 + pos.captures_to_hand() + !!pos.max_check_count()); ++ score -= FlankAttacks * kingFlankAttacks * (1 + pos.captures_to_hand() + !!pos.max_check_count()); + + // For drop games, king danger is independent of game phase + if (pos.captures_to_hand()) + score = make_score(mg_value(score), mg_value(score)) / (1 + !pos.shogi_doubled_pawn()); if (T) Trace::add(KING, Us, score); @@@ -1086,10 -855,10 +1088,10 @@@ // Interpolate between a middlegame and a (scaled by 'sf') endgame score ScaleFactor sf = scale_factor(eg_value(score)); - v = mg_value(score) * int(me->game_phase()) - + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL; + Value v = mg_value(score) * int(me->game_phase()) + + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL; - v /= int(PHASE_MIDGAME); + v /= PHASE_MIDGAME; // In case of tracing add all remaining individual evaluation terms if (T) diff --cc src/psqt.cpp index 4a55500,cba6bb0..f34d891 --- a/src/psqt.cpp +++ b/src/psqt.cpp @@@ -68,36 -59,35 +68,36 @@@ constexpr Score Bonus[PIECE_TYPE_NB][RA { S(-48,-51), S( -3,-40), S(-12,-39), S(-25,-20) } }, { // Rook - { S(-24, -2), S(-13,-6), S( -7, -3), S( 2,-2) }, - { S(-18,-10), S(-10,-7), S( -5, 1), S( 9, 0) }, - { S(-21, 10), S( -7,-4), S( 3, 2), S(-1,-2) }, - { S(-13, -5), S( -5, 2), S( -4, -8), S(-6, 8) }, - { S(-24, -8), S(-12, 5), S( -1, 4), S( 6,-9) }, - { S(-24, 3), S( -4,-2), S( 4,-10), S(10, 7) }, - { S( -8, 1), S( 6, 2), S( 10, 17), S(12,-8) }, - { S(-22, 12), S(-24,-6), S( -6, 13), S( 4, 7) } + { S(-24, -2), S(-13,-6), S(-7, -3), S( 2,-2) }, + { S(-18,-10), S(-10,-7), S(-5, 1), S( 9, 0) }, + { S(-21, 10), S( -7,-4), S( 3, 2), S(-1,-2) }, + { S(-13, -5), S( -5, 2), S(-4, -8), S(-6, 8) }, + { S(-24, -8), S(-12, 5), S(-1, 4), S( 6,-9) }, + { S(-24, 3), S( -4,-2), S( 4,-10), S(10, 7) }, + { S( -8, 1), S( 6, 2), S(10, 17), S(12,-8) }, + { S(-22, 12), S(-24,-6), S(-6, 13), S( 4, 7) } }, { // Queen - { S( 3,-69), S(-5,-57), S(-5,-47), S( 4,-26) }, - { S( -3,-55), S( 5,-31), S( 8,-22), S(12, -4) }, - { S( -3,-39), S( 6,-18), S(13, -9), S( 7, 3) }, - { S( 4,-23), S( 5, -3), S( 9, 13), S( 8, 24) }, - { S( 0,-29), S(14, -6), S(12, 9), S( 5, 21) }, - { S( -4,-38), S(10,-18), S( 6,-12), S( 8, 1) }, - { S( -5,-50), S( 6,-27), S(10,-24), S( 8, -8) }, - { S( -2,-75), S(-2,-52), S( 1,-43), S(-2,-36) } + { S( 3,-69), S(-5,-57), S(-5,-47), S( 4,-26) }, + { S(-3,-55), S( 5,-31), S( 8,-22), S(12, -4) }, + { S(-3,-39), S( 6,-18), S(13, -9), S( 7, 3) }, + { S( 4,-23), S( 5, -3), S( 9, 13), S( 8, 24) }, + { S( 0,-29), S(14, -6), S(12, 9), S( 5, 21) }, + { S(-4,-38), S(10,-18), S( 6,-12), S( 8, 1) }, + { S(-5,-50), S( 6,-27), S(10,-24), S( 8, -8) }, + { S(-2,-75), S(-2,-52), S( 1,-43), S(-2,-36) } - }, - { // King + } +}; + +constexpr Score KingBonus[RANK_NB][int(FILE_NB) / 2] = { { S(272, 0), S(325, 41), S(273, 80), S(190, 93) }, { S(277, 57), S(305, 98), S(241,138), S(183,131) }, { S(198, 86), S(253,138), S(168,165), S(120,173) }, { S(169,103), S(191,152), S(136,168), S(108,169) }, - { S(145, 98), S(176,166), S(112,197), S(69, 194) }, - { S(122, 87), S(159,164), S(85, 174), S(36, 189) }, - { S(87, 40), S(120, 99), S(64, 128), S(25, 141) }, - { S(64, 5), S(87, 60), S(49, 75), S(0, 75) } + { S(145, 98), S(176,166), S(112,197), S( 69,194) }, + { S(122, 87), S(159,164), S( 85,174), S( 36,189) }, + { S( 87, 40), S(120, 99), S( 64,128), S( 25,141) }, + { S( 64, 5), S( 87, 60), S( 49, 75), S( 0, 75) } - } }; constexpr Score PBonus[RANK_NB][FILE_NB] = diff --cc src/search.cpp index 65c4404,c6b59b3..f1bc6ef --- a/src/search.cpp +++ b/src/search.cpp @@@ -758,9 -749,9 +754,9 @@@ namespace ss->staticEval = eval = pureStaticEval + bonus; } else - ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::Tempo; + ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::tempo_value(pos); - tte->save(posKey, VALUE_NONE, pvHit, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval); + tte->save(posKey, VALUE_NONE, ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval); } // Step 7. Razoring (~2 Elo)