From: Marco Costalba Date: Fri, 6 Mar 2009 15:29:46 +0000 (+0100) Subject: Introduce evaluate_pieces<>() to remove redundancy X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=3e663d8c50310a7a66043a2cdeb70cc83c2d269d Introduce evaluate_pieces<>() to remove redundancy No functional change. Signed-off-by: Marco Costalba --- diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 269e8062..9368aa2c 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -272,11 +272,11 @@ namespace { uint8_t BitCount8Bit[256]; // Function prototypes - void evaluate_knight(const Position &p, Square s, Color us, EvalInfo &ei); - void evaluate_bishop(const Position &p, Square s, Color us, EvalInfo &ei); - void evaluate_rook(const Position &p, Square s, Color us, EvalInfo &ei); - void evaluate_queen(const Position &p, Square s, Color us, EvalInfo &ei); - void evaluate_king(const Position &p, Square s, Color us, EvalInfo &ei); + template + void evaluate_pieces(const Position& p, Color us, EvalInfo& ei); + + template<> + void evaluate_pieces(const Position& p, Color us, EvalInfo &ei); void evaluate_passed_pawns(const Position &pos, EvalInfo &ei); void evaluate_trapped_bishop_a7h7(const Position &pos, Square s, Color us, @@ -352,52 +352,22 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { // Evaluate pieces for (Color c = WHITE; c <= BLACK; c++) { - // Knights - for (int i = 0; i < pos.piece_count(c, KNIGHT); i++) - evaluate_knight(pos, pos.piece_list(c, KNIGHT, i), c, ei); - - // Bishops - for (int i = 0; i < pos.piece_count(c, BISHOP); i++) - evaluate_bishop(pos, pos.piece_list(c, BISHOP, i), c, ei); - - // Rooks - for (int i = 0; i < pos.piece_count(c, ROOK); i++) - evaluate_rook(pos, pos.piece_list(c, ROOK, i), c, ei); - - // Queens - for(int i = 0; i < pos.piece_count(c, QUEEN); i++) - evaluate_queen(pos, pos.piece_list(c, QUEEN, i), c, ei); - - // Special pattern: trapped bishops on a7/h7/a2/h2 - Bitboard b = pos.bishops(c) & MaskA7H7[c]; - while (b) - { - Square s = pop_1st_bit(&b); - evaluate_trapped_bishop_a7h7(pos, s, c, ei); - } - - // Special pattern: trapped bishops on a1/h1/a8/h8 in Chess960: - if (Chess960) - { - b = pos.bishops(c) & MaskA1H1[c]; - while (b) - { - Square s = pop_1st_bit(&b); - evaluate_trapped_bishop_a1h1(pos, s, c, ei); - } - } - - // Sum up all attacked squares - ei.attackedBy[c][0] = ei.attackedBy[c][PAWN] | ei.attackedBy[c][KNIGHT] - | ei.attackedBy[c][BISHOP] | ei.attackedBy[c][ROOK] - | ei.attackedBy[c][QUEEN] | ei.attackedBy[c][KING]; + evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); + + // Sum up all attacked squares + ei.attackedBy[c][0] = ei.attackedBy[c][PAWN] | ei.attackedBy[c][KNIGHT] + | ei.attackedBy[c][BISHOP] | ei.attackedBy[c][ROOK] + | ei.attackedBy[c][QUEEN] | ei.attackedBy[c][KING]; } // Kings. Kings are evaluated after all other pieces for both sides, // because we need complete attack information for all pieces when computing // the king safety evaluation. for (Color c = WHITE; c <= BLACK; c++) - evaluate_king(pos, pos.king_square(c), c, ei); + evaluate_pieces(pos, c, ei); // Evaluate passed pawns. We evaluate passed pawns for both sides at once, // because we need to know which side promotes first in positions where @@ -616,109 +586,98 @@ namespace { } - // evaluate_knight() assigns bonuses and penalties to a knight of a given - // color on a given square. + // evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given + // color. - void evaluate_knight(const Position& p, Square s, Color us, EvalInfo& ei) { + template + void evaluate_pieces(const Position& pos, Color us, EvalInfo& ei) { - // Attacks, mobility and outposts - evaluate_common(p, p.piece_attacks(s), us, ei, s); - } + Bitboard b; + for (int i = 0; i < pos.piece_count(us, Piece); i++) + { + Square s = pos.piece_list(us, Piece, i); - // evaluate_bishop() assigns bonuses and penalties to a bishop of a given - // color on a given square. + if (Piece == KNIGHT || Piece == QUEEN) + b = pos.piece_attacks(s); + else if (Piece == BISHOP) + b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.queens(us)); + else if (Piece == ROOK) + b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.rooks_and_queens(us)); - void evaluate_bishop(const Position& p, Square s, Color us, EvalInfo& ei) { + // Attacks, mobility and outposts + int mob = evaluate_common(pos, b, us, ei, s); - Bitboard b = bishop_attacks_bb(s, p.occupied_squares() & ~p.queens(us)); + // Special patterns: trapped bishops on a7/h7/a2/h2 + // and trapped bishops on a1/h1/a8/h8 in Chess960. + if (Piece == BISHOP) + { + if (bit_is_set(MaskA7H7[us], s)) + evaluate_trapped_bishop_a7h7(pos, s, us, ei); - // Attacks, mobility and outposts - evaluate_common(p, b, us, ei, s); - } + if (Chess960 && bit_is_set(MaskA1H1[us], s)) + evaluate_trapped_bishop_a1h1(pos, s, us, ei); + } + if (Piece != ROOK && Piece != QUEEN) + continue; - // evaluate_rook() assigns bonuses and penalties to a rook of a given - // color on a given square. + // Queen or rook on 7th rank + Color them = opposite_color(us); - void evaluate_rook(const Position& p, Square s, Color us, EvalInfo& ei) { + if ( relative_rank(us, s) == RANK_7 + && relative_rank(us, pos.king_square(them)) == RANK_8) + { + ei.mgValue += Sign[us] * (Piece == ROOK ? MidgameRookOn7thBonus : MidgameQueenOn7thBonus); + ei.egValue += Sign[us] * (Piece == ROOK ? EndgameRookOn7thBonus : EndgameQueenOn7thBonus); + } - Bitboard b = rook_attacks_bb(s, p.occupied_squares() & ~p.rooks_and_queens(us)); + // Special extra evaluation for rooks + if (Piece != ROOK) + continue; - // Attacks and mobility - int mob = evaluate_common(p, b, us, ei); + // Open and half-open files + File f = square_file(s); + if (ei.pi->file_is_half_open(us, f)) + { + if (ei.pi->file_is_half_open(them, f)) + { + ei.mgValue += Sign[us] * RookOpenFileBonus; + ei.egValue += Sign[us] * RookOpenFileBonus; + } + else + { + ei.mgValue += Sign[us] * RookHalfOpenFileBonus; + ei.egValue += Sign[us] * RookHalfOpenFileBonus; + } + } - // Rook on 7th rank - Color them = opposite_color(us); + // Penalize rooks which are trapped inside a king. Penalize more if + // king has lost right to castle. + if (mob > 6 || ei.pi->file_is_half_open(us, f)) + continue; - if ( relative_rank(us, s) == RANK_7 - && relative_rank(us, p.king_square(them)) == RANK_8) - { - ei.mgValue += Sign[us] * MidgameRookOn7thBonus; - ei.egValue += Sign[us] * EndgameRookOn7thBonus; - } + Square ksq = pos.king_square(us); - // Open and half-open files - File f = square_file(s); - if (ei.pi->file_is_half_open(us, f)) - { - if (ei.pi->file_is_half_open(them, f)) + if ( square_file(ksq) >= FILE_E + && square_file(s) > square_file(ksq) + && (relative_rank(us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s))) { - ei.mgValue += Sign[us] * RookOpenFileBonus; - ei.egValue += Sign[us] * RookOpenFileBonus; + // Is there a half-open file between the king and the edge of the board? + if (!ei.pi->has_open_file_to_right(us, square_file(ksq))) + ei.mgValue -= pos.can_castle(us)? Sign[us] * ((TrappedRookPenalty - mob * 16) / 2) + : Sign[us] * (TrappedRookPenalty - mob * 16); } - else + else if ( square_file(ksq) <= FILE_D + && square_file(s) < square_file(ksq) + && (relative_rank(us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s))) { - ei.mgValue += Sign[us] * RookHalfOpenFileBonus; - ei.egValue += Sign[us] * RookHalfOpenFileBonus; + // Is there a half-open file between the king and the edge of the board? + if (!ei.pi->has_open_file_to_left(us, square_file(ksq))) + ei.mgValue -= pos.can_castle(us)? Sign[us] * ((TrappedRookPenalty - mob * 16) / 2) + : Sign[us] * (TrappedRookPenalty - mob * 16); } } - - // Penalize rooks which are trapped inside a king. Penalize more if - // king has lost right to castle - if (mob > 6 || ei.pi->file_is_half_open(us, f)) - return; - - Square ksq = p.king_square(us); - - if ( square_file(ksq) >= FILE_E - && square_file(s) > square_file(ksq) - && (relative_rank(us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s))) - { - // Is there a half-open file between the king and the edge of the board? - if (!ei.pi->has_open_file_to_right(us, square_file(ksq))) - ei.mgValue -= p.can_castle(us)? Sign[us] * ((TrappedRookPenalty - mob * 16) / 2) - : Sign[us] * (TrappedRookPenalty - mob * 16); - } - else if ( square_file(ksq) <= FILE_D - && square_file(s) < square_file(ksq) - && (relative_rank(us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s))) - { - // Is there a half-open file between the king and the edge of the board? - if (!ei.pi->has_open_file_to_left(us, square_file(ksq))) - ei.mgValue -= p.can_castle(us)? Sign[us] * ((TrappedRookPenalty - mob * 16) / 2) - : Sign[us] * (TrappedRookPenalty - mob * 16); - } - } - - - // evaluate_queen() assigns bonuses and penalties to a queen of a given - // color on a given square. - - void evaluate_queen(const Position& p, Square s, Color us, EvalInfo& ei) { - - // Attacks and mobility - evaluate_common(p, p.piece_attacks(s), us, ei); - - // Queen on 7th rank - Color them = opposite_color(us); - - if ( relative_rank(us, s) == RANK_7 - && relative_rank(us, p.king_square(them)) == RANK_8) - { - ei.mgValue += Sign[us] * MidgameQueenOn7thBonus; - ei.egValue += Sign[us] * EndgameQueenOn7thBonus; - } } inline Bitboard shiftRowsDown(const Bitboard& b, int num) { @@ -726,12 +685,14 @@ namespace { return b >> (num << 3); } - // evaluate_king() assigns bonuses and penalties to a king of a given - // color on a given square. + // evaluate_pieces() assigns bonuses and penalties to a king of a given + // color. - void evaluate_king(const Position& p, Square s, Color us, EvalInfo& ei) { + template<> + void evaluate_pieces(const Position& p, Color us, EvalInfo& ei) { int shelter = 0, sign = Sign[us]; + Square s = p.king_square(us); // King shelter if (relative_rank(us, s) <= RANK_4)