X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=6f6141bafd37e0c3f0701376cd47f8a85523e107;hp=4d47b7e6df64a681bdc1b979626a04d942643d32;hb=ce159b16b9483f83b9e96ac6bf3d6e2ba7e5619c;hpb=0439a79566d03065317b2025b9b479b9ae9f2d65 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 4d47b7e6..6f6141ba 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 = Threads[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 = Threads[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)))]; } @@ -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) @@ -893,14 +896,14 @@ Value do_evaluate(const Position& pos, Value& margin) { // If the pawn is free to advance, increase bonus if (pos.square_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);