1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 09:13:08 +00:00

Introduce namespace Material

And retire old struct MaterialTable simplifying the code.

No functional change.
This commit is contained in:
Marco Costalba 2012-12-16 12:00:54 +01:00
parent 52bbf372bb
commit 231f62baf7
6 changed files with 72 additions and 104 deletions

View file

@ -36,7 +36,7 @@ namespace {
struct EvalInfo { struct EvalInfo {
// Pointers to material and pawn hash table entries // Pointers to material and pawn hash table entries
MaterialEntry* mi; Material::Entry* mi;
PawnEntry* pi; PawnEntry* pi;
// attackedBy[color][piece type] is a bitboard representing all squares // attackedBy[color][piece type] is a bitboard representing all squares
@ -367,7 +367,8 @@ Value do_evaluate(const Position& pos, Value& margin) {
Score score, mobilityWhite, mobilityBlack; Score score, mobilityWhite, mobilityBlack;
Key key = pos.key(); Key key = pos.key();
Eval::Entry* e = pos.this_thread()->evalTable[key]; Thread* th = pos.this_thread();
Eval::Entry* e = th->evalTable[key];
// If e->key matches the position's hash key, it means that we have analysed // If e->key matches the position's hash key, it means that we have analysed
// this node before, and we can simply return the information we found the last // this node before, and we can simply return the information we found the last
@ -391,7 +392,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
score = pos.psq_score() + (pos.side_to_move() == WHITE ? Tempo : -Tempo); score = pos.psq_score() + (pos.side_to_move() == WHITE ? Tempo : -Tempo);
// Probe the material hash table // Probe the material hash table
ei.mi = pos.this_thread()->materialTable.probe(pos); ei.mi = Material::probe(pos, th->materialTable, th->endgames);
score += ei.mi->material_value(); score += ei.mi->material_value();
// If we have a specialized evaluation function for the current material // If we have a specialized evaluation function for the current material

View file

@ -17,7 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <algorithm> #include <algorithm> // For std::min
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
@ -81,18 +81,54 @@ namespace {
&& pos.piece_count(Them, PAWN) >= 1; && pos.piece_count(Them, PAWN) >= 1;
} }
/// imbalance() calculates imbalance comparing piece count of each
/// piece type for both colors.
template<Color Us>
int imbalance(const int pieceCount[][PIECE_TYPE_NB]) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
int pt1, pt2, pc, v;
int value = 0;
// Redundancy of major pieces, formula based on Kaufman's paper
// "The Evaluation of Material Imbalances in Chess"
if (pieceCount[Us][ROOK] > 0)
value -= RedundantRookPenalty * (pieceCount[Us][ROOK] - 1)
+ RedundantQueenPenalty * pieceCount[Us][QUEEN];
// Second-degree polynomial material imbalance by Tord Romstad
for (pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; pt1++)
{
pc = pieceCount[Us][pt1];
if (!pc)
continue;
v = LinearCoefficients[pt1];
for (pt2 = NO_PIECE_TYPE; pt2 <= pt1; pt2++)
v += QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2]
+ QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2];
value += pc * v;
}
return value;
}
} // namespace } // namespace
namespace Material {
/// MaterialTable::probe() takes a position object as input, looks up a MaterialEntry /// Material::probe() takes a position object as input, looks up a MaterialEntry
/// object, and returns a pointer to it. If the material configuration is not /// object, and returns a pointer to it. If the material configuration is not
/// already present in the table, it is computed and stored there, so we don't /// already present in the table, it is computed and stored there, so we don't
/// have to recompute everything when the same material configuration occurs again. /// have to recompute everything when the same material configuration occurs again.
MaterialEntry* MaterialTable::probe(const Position& pos) { Entry* probe(const Position& pos, Table& entries, Endgames& endgames) {
Key key = pos.material_key(); Key key = pos.material_key();
MaterialEntry* e = entries[key]; Entry* e = entries[key];
// If e->key matches the position's material hash key, it means that we // If e->key matches the position's material hash key, it means that we
// have analysed this material configuration before, and we can simply // have analysed this material configuration before, and we can simply
@ -100,10 +136,10 @@ MaterialEntry* MaterialTable::probe(const Position& pos) {
if (e->key == key) if (e->key == key)
return e; return e;
memset(e, 0, sizeof(MaterialEntry)); memset(e, 0, sizeof(Entry));
e->key = key; e->key = key;
e->factor[WHITE] = e->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL; e->factor[WHITE] = e->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
e->gamePhase = MaterialTable::game_phase(pos); e->gamePhase = game_phase(pos);
// Let's look if we have a specialized evaluation function for this // Let's look if we have a specialized evaluation function for this
// particular material configuration. First we look for a fixed // particular material configuration. First we look for a fixed
@ -226,47 +262,11 @@ MaterialEntry* MaterialTable::probe(const Position& pos) {
} }
/// MaterialTable::imbalance() calculates imbalance comparing piece count of each /// Material::game_phase() calculates the phase given the current
/// piece type for both colors.
template<Color Us>
int MaterialTable::imbalance(const int pieceCount[][PIECE_TYPE_NB]) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
int pt1, pt2, pc, v;
int value = 0;
// Redundancy of major pieces, formula based on Kaufman's paper
// "The Evaluation of Material Imbalances in Chess"
if (pieceCount[Us][ROOK] > 0)
value -= RedundantRookPenalty * (pieceCount[Us][ROOK] - 1)
+ RedundantQueenPenalty * pieceCount[Us][QUEEN];
// Second-degree polynomial material imbalance by Tord Romstad
for (pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; pt1++)
{
pc = pieceCount[Us][pt1];
if (!pc)
continue;
v = LinearCoefficients[pt1];
for (pt2 = NO_PIECE_TYPE; pt2 <= pt1; pt2++)
v += QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2]
+ QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2];
value += pc * v;
}
return value;
}
/// MaterialTable::game_phase() calculates the phase given the current
/// position. Because the phase is strictly a function of the material, it /// position. Because the phase is strictly a function of the material, it
/// is stored in MaterialEntry. /// is stored in MaterialEntry.
Phase MaterialTable::game_phase(const Position& pos) { Phase game_phase(const Position& pos) {
Value npm = pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK); Value npm = pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK);
@ -274,3 +274,5 @@ Phase MaterialTable::game_phase(const Position& pos) {
: npm <= EndgameLimit ? PHASE_ENDGAME : npm <= EndgameLimit ? PHASE_ENDGAME
: Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit)); : Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit));
} }
} // namespace Material

View file

@ -25,31 +25,26 @@
#include "position.h" #include "position.h"
#include "types.h" #include "types.h"
const int MaterialTableSize = 8192; namespace Material {
/// MaterialEntry is a class which contains various information about a /// Material::Entry contains various information about a material configuration.
/// material configuration. It contains a material balance evaluation, /// It contains a material balance evaluation, a function pointer to a special
/// a function pointer to a special endgame evaluation function (which in /// endgame evaluation function (which in most cases is NULL, meaning that the
/// most cases is NULL, meaning that the standard evaluation function will /// standard evaluation function will be used), and "scale factors".
/// be used), and "scale factors" for black and white.
/// ///
/// The scale factors are used to scale the evaluation score up or down. /// The scale factors are used to scale the evaluation score up or down.
/// For instance, in KRB vs KR endgames, the score is scaled down by a factor /// For instance, in KRB vs KR endgames, the score is scaled down by a factor
/// of 4, which will result in scores of absolute value less than one pawn. /// of 4, which will result in scores of absolute value less than one pawn.
class MaterialEntry { struct Entry {
friend struct MaterialTable; Score material_value() const { return make_score(value, value); }
int space_weight() const { return spaceWeight; }
public: Phase game_phase() const { return gamePhase; }
Score material_value() const; bool specialized_eval_exists() const { return evaluationFunction != NULL; }
Value evaluate(const Position& p) const { return (*evaluationFunction)(p); }
ScaleFactor scale_factor(const Position& pos, Color c) const; ScaleFactor scale_factor(const Position& pos, Color c) const;
int space_weight() const;
Phase game_phase() const;
bool specialized_eval_exists() const;
Value evaluate(const Position& pos) const;
private:
Key key; Key key;
int16_t value; int16_t value;
uint8_t factor[COLOR_NB]; uint8_t factor[COLOR_NB];
@ -59,55 +54,24 @@ private:
Phase gamePhase; Phase gamePhase;
}; };
typedef HashTable<Entry, 8192> Table;
/// The MaterialTable class represents a material hash table. The most important Entry* probe(const Position& pos, Table& entries, Endgames& endgames);
/// method is probe(), which returns a pointer to a MaterialEntry object. Phase game_phase(const Position& pos);
struct MaterialTable { /// Material::scale_factor takes a position and a color as input, and
MaterialEntry* probe(const Position& pos);
static Phase game_phase(const Position& pos);
template<Color Us> static int imbalance(const int pieceCount[][PIECE_TYPE_NB]);
HashTable<MaterialEntry, MaterialTableSize> entries;
Endgames endgames;
};
/// MaterialEntry::scale_factor takes a position and a color as input, and
/// returns a scale factor for the given color. We have to provide the /// returns a scale factor for the given color. We have to provide the
/// position in addition to the color, because the scale factor need not /// position in addition to the color, because the scale factor need not
/// to be a constant: It can also be a function which should be applied to /// to be a constant: It can also be a function which should be applied to
/// the position. For instance, in KBP vs K endgames, a scaling function /// the position. For instance, in KBP vs K endgames, a scaling function
/// which checks for draws with rook pawns and wrong-colored bishops. /// which checks for draws with rook pawns and wrong-colored bishops.
inline ScaleFactor MaterialEntry::scale_factor(const Position& pos, Color c) const { inline ScaleFactor Entry::scale_factor(const Position& pos, Color c) const {
if (!scalingFunction[c]) return !scalingFunction[c] || (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE
return ScaleFactor(factor[c]); ? ScaleFactor(factor[c]) : (*scalingFunction[c])(pos);
ScaleFactor sf = (*scalingFunction[c])(pos);
return sf == SCALE_FACTOR_NONE ? ScaleFactor(factor[c]) : sf;
} }
inline Value MaterialEntry::evaluate(const Position& pos) const {
return (*evaluationFunction)(pos);
}
inline Score MaterialEntry::material_value() const {
return make_score(value, value);
}
inline int MaterialEntry::space_weight() const {
return spaceWeight;
}
inline Phase MaterialEntry::game_phase() const {
return gamePhase;
}
inline bool MaterialEntry::specialized_eval_exists() const {
return evaluationFunction != NULL;
} }
#endif // !defined(MATERIAL_H_INCLUDED) #endif // !defined(MATERIAL_H_INCLUDED)

View file

@ -919,7 +919,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
// Prefetch pawn and material hash tables // Prefetch pawn and material hash tables
prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]); prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]);
prefetch((char*)thisThread->materialTable.entries[st->materialKey]); prefetch((char*)thisThread->materialTable[st->materialKey]);
// Update incremental scores // Update incremental scores
st->psqScore += psq_delta(piece, from, to); st->psqScore += psq_delta(piece, from, to);

View file

@ -208,7 +208,7 @@ void Search::think() {
if (Options["Contempt Factor"] && !Options["UCI_AnalyseMode"]) if (Options["Contempt Factor"] && !Options["UCI_AnalyseMode"])
{ {
int cf = Options["Contempt Factor"] * PawnValueMg / 100; // From centipawns int cf = Options["Contempt Factor"] * PawnValueMg / 100; // From centipawns
cf = cf * MaterialTable::game_phase(RootPos) / PHASE_MIDGAME; // Scale down with phase cf = cf * Material::game_phase(RootPos) / PHASE_MIDGAME; // Scale down with phase
DrawValue[ RootColor] = VALUE_DRAW - Value(cf); DrawValue[ RootColor] = VALUE_DRAW - Value(cf);
DrawValue[~RootColor] = VALUE_DRAW + Value(cf); DrawValue[~RootColor] = VALUE_DRAW + Value(cf);
} }

View file

@ -110,7 +110,8 @@ public:
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD]; SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
Eval::Table evalTable; Eval::Table evalTable;
MaterialTable materialTable; Material::Table materialTable;
Endgames endgames;
PawnTable pawnTable; PawnTable pawnTable;
size_t idx; size_t idx;
int maxPly; int maxPly;