diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 9bb6c1c0..5f86227c 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -430,6 +430,13 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) { factor[BLACK] = sf; } + // If we don't already have an unusual scale factor, use pawn + // evaluation ones. + if (factor[WHITE] == SCALE_FACTOR_NORMAL) + factor[WHITE] = ei.pi->scale_factor(WHITE); + if (factor[BLACK] == SCALE_FACTOR_NORMAL) + factor[BLACK] = ei.pi->scale_factor(BLACK); + // Interpolate between the middle game and the endgame score Color stm = pos.side_to_move(); diff --git a/src/material.cpp b/src/material.cpp index 65c8c862..f0ee5f68 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -304,7 +304,7 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) { { if ( pos.non_pawn_material(c) == pos.non_pawn_material(opposite_color(c)) || pos.non_pawn_material(c) < RookValueMidgame) - mi->factor[c] = 0; + mi->factor[c] = SCALE_FACTOR_ZERO; else { switch (pos.piece_count(c, BISHOP)) { diff --git a/src/pawns.cpp b/src/pawns.cpp index df7a0a2d..b381b5c4 100644 --- a/src/pawns.cpp +++ b/src/pawns.cpp @@ -70,6 +70,13 @@ namespace { S(34,68), S(83,166), S(0, 0), S( 0, 0) }; + // UnpairedPawnsTable[] gives a score according to the number + // of panws that do not have an enemy pawn in front of them. + const int UnpairedPawnsTable[8] = { + SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, + SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL + }; + // Pawn storm tables for positions with opposite castling const int QStormTable[64] = { 0, 0, 0, 0, 0, 0, 0, 0, @@ -187,6 +194,7 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns, int bonus; Score value = make_score(0, 0); const Square* ptr = pos.piece_list_begin(Us, PAWN); + int unpairedPawnsNum = pos.piece_count(Us, PAWN); // Initialize pawn storm scores by giving bonuses for open files for (f = FILE_A; f <= FILE_H; f++) @@ -211,6 +219,10 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns, doubled = ourPawns & squares_behind(Us, s); opposed = theirPawns & squares_in_front_of(Us, s); + // Decrease number of unpaired pawns + if (opposed) + unpairedPawnsNum--; + // We calculate kingside and queenside pawn storm // scores for both colors. These are used when evaluating // middle game positions with opposite side castling. @@ -337,6 +349,9 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns, value += CandidateBonus[relative_rank(Us, s)]; } + // Calculate a scale factor to be used to evaluate if position is drawish + pi->factor[Us] = UnpairedPawnsTable[unpairedPawnsNum]; + return value; } diff --git a/src/pawns.h b/src/pawns.h index 2dc86684..5939253b 100644 --- a/src/pawns.h +++ b/src/pawns.h @@ -26,6 +26,7 @@ //// #include "bitboard.h" +#include "scale.h" #include "value.h" //// @@ -52,6 +53,7 @@ public: Value queenside_storm_value(Color c) const; Bitboard pawn_attacks(Color c) const; Bitboard passed_pawns() const; + ScaleFactor scale_factor(Color c) const; int file_is_half_open(Color c, File f) const; int has_open_file_to_left(Color c, File f) const; int has_open_file_to_right(Color c, File f) const; @@ -67,8 +69,7 @@ private: Square kingSquares[2]; Score value; int16_t ksStormValue[2], qsStormValue[2]; - uint8_t halfOpenFiles[2]; - uint8_t kingShelters[2]; + uint8_t halfOpenFiles[2], kingShelters[2], factor[2]; }; /// The PawnInfoTable class represents a pawn hash table. It is basically @@ -116,6 +117,10 @@ inline Value PawnInfo::queenside_storm_value(Color c) const { return Value(qsStormValue[c]); } +inline ScaleFactor PawnInfo::scale_factor(Color c) const { + return ScaleFactor(factor[c]); +} + inline int PawnInfo::file_is_half_open(Color c, File f) const { return (halfOpenFiles[c] & (1 << int(f))); } diff --git a/src/scale.h b/src/scale.h index a02cc764..bcf37dd4 100644 --- a/src/scale.h +++ b/src/scale.h @@ -33,10 +33,10 @@ //// enum ScaleFactor { - SCALE_FACTOR_ZERO = 0, + SCALE_FACTOR_ZERO = 0, SCALE_FACTOR_NORMAL = 64, - SCALE_FACTOR_MAX = 128, - SCALE_FACTOR_NONE = 255 + SCALE_FACTOR_MAX = 128, + SCALE_FACTOR_NONE = 255 };