From: Fabian Fichter Date: Sun, 9 Aug 2020 13:05:49 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=a043c2eb93dd14aa3130e2bfc9f9b098f5401112;p=fairystockfish.git Merge official-stockfish/master bench: 4988792 --- a043c2eb93dd14aa3130e2bfc9f9b098f5401112 diff --cc src/evaluate.cpp index 079171d,67e0592..39a1c92 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -79,15 -78,14 +79,16 @@@ namespace constexpr Value SpaceThreshold = Value(12222); // KingAttackWeights[PieceType] contains king attack weights by piece type - constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 }; + constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10, 40 }; // Penalties for enemy's safe checks - constexpr int QueenSafeCheck = 780; - constexpr int RookSafeCheck = 1078; - constexpr int BishopSafeCheck = 635; - constexpr int KnightSafeCheck = 790; + constexpr int QueenSafeCheck = 772; + constexpr int RookSafeCheck = 1084; + constexpr int BishopSafeCheck = 645; + constexpr int KnightSafeCheck = 792; + + constexpr int OtherSafeCheck = 600; + #define S(mg, eg) make_score(mg, eg) // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game, @@@ -363,8 -305,8 +366,9 @@@ score += MinorBehindPawn; // Penalty if the piece is far from the king + if (pos.count(Us)) - score -= KingProtector * distance(pos.square(Us), s); + score -= (Pt == KNIGHT ? KnightKingProtector + : BishopKingProtector) * distance(pos.square(Us), s); if (Pt == BISHOP) { @@@ -489,78 -399,44 +493,78 @@@ b1 = attacks_bb(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)); b2 = attacks_bb(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)); - // Enemy rooks checks - rookChecks = b1 & safe & attackedBy[Them][ROOK]; - if (rookChecks) - kingDanger += more_than_one(rookChecks) ? RookSafeCheck * 175/100 - : RookSafeCheck; - else - unsafeChecks |= b1 & attackedBy[Them][ROOK]; - - // Enemy queen safe checks: we count them only if they are from squares from - // which we can't give a rook check, because rook checks are more valuable. - queenChecks = (b1 | b2) - & attackedBy[Them][QUEEN] - & safe - & ~attackedBy[Us][QUEEN] - & ~rookChecks; - if (queenChecks) - kingDanger += more_than_one(queenChecks) ? QueenSafeCheck * 145/100 - : QueenSafeCheck; - - // Enemy bishops checks: we count them only if they are from squares from - // which we can't give a queen check, because queen checks are more valuable. - bishopChecks = b2 - & attackedBy[Them][BISHOP] - & safe - & ~queenChecks; - if (bishopChecks) - kingDanger += more_than_one(bishopChecks) ? BishopSafeCheck * 3/2 - : BishopSafeCheck; - else - unsafeChecks |= b2 & attackedBy[Them][BISHOP]; + std::function get_attacks = [this](Color c, PieceType pt) { + return attackedBy[c][pt] | (pos.piece_drops() && pos.count_in_hand(c, pt) ? pos.drop_region(c, pt) & ~pos.pieces() : Bitboard(0)); + }; + for (PieceType pt : pos.piece_types()) + { + switch (pt) + { + case QUEEN: + // Enemy queen safe checks: we count them only if they are from squares from + // which we can't give a rook check, because rook checks are more valuable. + queenChecks = (b1 | b2) + & get_attacks(Them, QUEEN) + & pos.board_bb() + & safe + & ~attackedBy[Us][QUEEN] + & ~(b1 & attackedBy[Them][ROOK]); + + if (queenChecks) - kingDanger += more_than_one(queenChecks) ? QueenSafeCheck * 3/2 ++ kingDanger += more_than_one(queenChecks) ? QueenSafeCheck * 145/100 + : QueenSafeCheck; + break; + case ROOK: + case BISHOP: + case KNIGHT: + knightChecks = attacks_bb(Us, pt, ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)) & get_attacks(Them, pt) & pos.board_bb(); + if (knightChecks & safe) - kingDanger += (pt == ROOK ? RookSafeCheck - : pt == BISHOP ? BishopSafeCheck - : KnightSafeCheck) * (more_than_one(knightChecks & safe) ? 3 : 2) / 2; ++ kingDanger += pt == ROOK ? RookSafeCheck * (more_than_one(knightChecks & safe) ? 175 : 100) / 100 ++ : pt == BISHOP ? BishopSafeCheck * (more_than_one(knightChecks & safe) ? 150 : 100) / 100 ++ : KnightSafeCheck * (more_than_one(knightChecks & safe) ? 162 : 100) / 100; + else + unsafeChecks |= knightChecks; + break; + case PAWN: + if (pos.piece_drops() && pos.count_in_hand(Them, pt)) + { + pawnChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & ~pos.pieces() & pos.board_bb(); + if (pawnChecks & safe) + kingDanger += OtherSafeCheck; + else + unsafeChecks |= pawnChecks; + } + break; + case SHOGI_PAWN: + case KING: + break; + default: + otherChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & get_attacks(Them, pt) & pos.board_bb(); + if (otherChecks & safe) + kingDanger += OtherSafeCheck * (more_than_one(otherChecks & safe) ? 3 : 2) / 2; + else + unsafeChecks |= otherChecks; + } + } - // Enemy knights checks - knightChecks = pos.attacks_from(ksq) & attackedBy[Them][KNIGHT]; - if (knightChecks & safe) - kingDanger += more_than_one(knightChecks & safe) ? KnightSafeCheck * 162/100 - : KnightSafeCheck; - else - unsafeChecks |= knightChecks; + // Virtual piece drops + if (pos.two_boards() && pos.piece_drops()) + { + for (PieceType pt : pos.piece_types()) + if (!pos.count_in_hand(Them, pt) && (attacks_bb(Us, pt, ksq, pos.pieces()) & safe & pos.drop_region(Them, pt) & ~pos.pieces())) + { + kingDanger += OtherSafeCheck * 500 / (500 + PieceValue[MG][pt]); + // Presumably a mate threat + if (!(attackedBy[Us][KING] & ~(attackedBy[Them][ALL_PIECES] | pos.pieces(Us)))) + kingDanger += 2000; + } + } + + if (pos.check_counting()) + kingDanger += kingDanger * 7 / (3 + pos.checks_remaining(Them)); + + Square s = file_of(ksq) == FILE_A ? ksq + EAST : file_of(ksq) == pos.max_file() ? ksq + WEST : ksq; + Bitboard kingFlank = pos.max_file() == FILE_H ? KingFlank[file_of(ksq)] : file_bb(s) | adjacent_files_bb(s); // Find the squares that opponent attacks in our king flank, the squares // which they attack twice in that flank, and the squares that we defend.