X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=9b755955f2d0b413b0e1e8c11b30ca1867afdce5;hp=db5e3fc25e79a39a282e1f05098e352b40944c6a;hb=5e905800887da94d481978d3bddd9539b2111458;hpb=673bc5526fa3d352f823ad144fb521b5dc98f45c diff --git a/src/evaluate.cpp b/src/evaluate.cpp index db5e3fc2..9b755955 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -150,6 +150,9 @@ namespace { #undef S + // Bonus for having the side to move (modified by Joona Kiiski) + const Score Tempo = make_score(24, 11); + // Rooks and queens on the 7th rank (modified by Joona Kiiski) const Score RookOn7thBonus = make_score(47, 98); const Score QueenOn7thBonus = make_score(27, 54); @@ -167,8 +170,8 @@ namespace { // happen in Chess960 games. const Score TrappedBishopA1H1Penalty = make_score(100, 100); - // Penalty for BNR that is not defended by anything - const Score UndefendedPiecePenalty = make_score(25, 10); + // Penalty for an undefended bishop or knight + const Score UndefendedMinorPenalty = make_score(25, 10); // The SpaceMask[Color] contains the area of the board which is considered // by the space evaluation. In the middle game, each side is given a bonus @@ -362,16 +365,17 @@ Value do_evaluate(const Position& pos, Value& margin) { Value margins[2]; Score score, mobilityWhite, mobilityBlack; - // Initialize score by reading the incrementally updated scores included - // in the position object (material + piece square tables). - score = pos.psq_score(); - // margins[] store the uncertainty estimation of position's evaluation // that typically is used by the search for pruning decisions. margins[WHITE] = margins[BLACK] = VALUE_ZERO; + // Initialize score by reading the incrementally updated scores included + // in the position object (material + piece square tables) and adding + // Tempo bonus. Score is computed from the point of view of white. + score = pos.psq_score() + (pos.side_to_move() == WHITE ? Tempo : -Tempo); + // Probe the material hash table - ei.mi = pos.this_thread().materialTable.probe(pos); + ei.mi = pos.this_thread()->materialTable.probe(pos); score += ei.mi->material_value(); // If we have a specialized evaluation function for the current material @@ -383,7 +387,7 @@ Value do_evaluate(const Position& pos, Value& margin) { } // Probe the pawn hash table - ei.pi = pos.this_thread().pawnTable.probe(pos); + ei.pi = pos.this_thread()->pawnTable.probe(pos); score += ei.pi->pawns_value(); // Initialize attack and king safety bitboards @@ -577,7 +581,7 @@ Value do_evaluate(const Position& pos, Value& margin) { assert(b); - if (single_bit(b) && (b & pos.pieces(Them))) + if (!more_than_one(b) && (b & pos.pieces(Them))) score += ThreatBonus[Piece][type_of(pos.piece_on(first_1(b)))]; } @@ -610,7 +614,7 @@ Value do_evaluate(const Position& pos, Value& margin) { Square d = pawn_push(Us) + (file_of(s) == FILE_A ? DELTA_E : DELTA_W); if (pos.piece_on(s + d) == make_piece(Us, PAWN)) { - if (!pos.square_empty(s + d + pawn_push(Us))) + if (!pos.is_empty(s + d + pawn_push(Us))) score -= 2*TrappedBishopA1H1Penalty; else if (pos.piece_on(s + 2*d) == make_piece(Us, PAWN)) score -= TrappedBishopA1H1Penalty; @@ -676,18 +680,17 @@ Value do_evaluate(const Position& pos, Value& margin) { const Color Them = (Us == WHITE ? BLACK : WHITE); - Bitboard b, undefended, undefendedMinors, weakEnemies; + Bitboard b, undefendedMinors, weakEnemies; Score score = SCORE_ZERO; - // Undefended pieces get penalized even if not under attack - undefended = pos.pieces(Them) & ~ei.attackedBy[Them][0]; - undefendedMinors = undefended & (pos.pieces(BISHOP) | pos.pieces(KNIGHT)); + // Undefended minors get penalized even if not under attack + undefendedMinors = pos.pieces(Them) + & (pos.pieces(BISHOP) | pos.pieces(KNIGHT)) + & ~ei.attackedBy[Them][0]; if (undefendedMinors) - score += single_bit(undefendedMinors) ? UndefendedPiecePenalty - : UndefendedPiecePenalty * 2; - if (undefended & pos.pieces(ROOK)) - score += UndefendedPiecePenalty; + score += more_than_one(undefendedMinors) ? UndefendedMinorPenalty * 2 + : UndefendedMinorPenalty; // Enemy pieces not defended by a pawn and under our attack weakEnemies = pos.pieces(Them) @@ -772,7 +775,7 @@ Value do_evaluate(const Position& pos, Value& margin) { attackUnits = std::min(25, (ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) / 2) + 3 * (ei.kingAdjacentZoneAttacksCount[Them] + popcount(undefended)) + InitKingDanger[relative_square(Us, ksq)] - - mg_value(ei.pi->king_safety(pos, ksq)) / 32; + - mg_value(score) / 32; // Analyse enemy's safe queen contact checks. First find undefended // squares around the king attacked by enemy queen... @@ -891,16 +894,16 @@ Value do_evaluate(const Position& pos, Value& margin) { ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr); // If the pawn is free to advance, increase bonus - if (pos.square_empty(blockSq)) + if (pos.is_empty(blockSq)) { - squaresToQueen = squares_in_front_of(Us, s); + squaresToQueen = forward_bb(Us, s); defendedSquares = squaresToQueen & ei.attackedBy[Us][0]; // If there is an enemy rook or queen attacking the pawn from behind, // add all X-ray attacks by the rook or queen. Otherwise consider only // the squares in the pawn's path attacked or occupied by the enemy. - if ( (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them)) - && (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from(s))) + if ( (forward_bb(Them, s) & pos.pieces(ROOK, QUEEN, Them)) + && (forward_bb(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from(s))) unsafeSquares = squaresToQueen; else unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces(Them)); @@ -975,7 +978,7 @@ Value do_evaluate(const Position& pos, Value& margin) { { s = pop_1st_bit(&b); queeningSquare = relative_square(c, make_square(file_of(s), RANK_8)); - queeningPath = squares_in_front_of(c, s); + queeningPath = forward_bb(c, s); // Compute plies to queening and check direct advancement movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2); @@ -1023,7 +1026,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // Check if (without even considering any obstacles) we're too far away or doubled if ( pliesToQueen[winnerSide] + 3 <= pliesToGo - || (squares_in_front_of(loserSide, s) & pos.pieces(PAWN, loserSide))) + || (forward_bb(loserSide, s) & pos.pieces(PAWN, loserSide))) candidates ^= s; } @@ -1047,7 +1050,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // Generate list of blocking pawns and supporters supporters = adjacent_files_bb(file_of(s)) & candidates; - opposed = squares_in_front_of(loserSide, s) & pos.pieces(PAWN, winnerSide); + opposed = forward_bb(loserSide, s) & pos.pieces(PAWN, winnerSide); blockers = passed_pawn_mask(loserSide, s) & pos.pieces(PAWN, winnerSide); assert(blockers); @@ -1105,7 +1108,7 @@ Value do_evaluate(const Position& pos, Value& margin) { } // Winning pawn is unstoppable and will promote as first, return big score - Score score = make_score(0, (Value) 0x500 - 0x20 * pliesToQueen[winnerSide]); + Score score = make_score(0, (Value) 1280 - 32 * pliesToQueen[winnerSide]); return winnerSide == WHITE ? score : -score; }