1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 16:53:09 +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 {
// Pointers to material and pawn hash table entries
MaterialEntry* mi;
Material::Entry* mi;
PawnEntry* pi;
// 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;
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
// 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);
// 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();
// 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/>.
*/
#include <algorithm>
#include <algorithm> // For std::min
#include <cassert>
#include <cstring>
@ -81,18 +81,54 @@ namespace {
&& 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 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
/// 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.
MaterialEntry* MaterialTable::probe(const Position& pos) {
Entry* probe(const Position& pos, Table& entries, Endgames& endgames) {
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
// have analysed this material configuration before, and we can simply
@ -100,10 +136,10 @@ MaterialEntry* MaterialTable::probe(const Position& pos) {
if (e->key == key)
return e;
memset(e, 0, sizeof(MaterialEntry));
memset(e, 0, sizeof(Entry));
e->key = key;
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
// 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
/// 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
/// Material::game_phase() calculates the phase given the current
/// position. Because the phase is strictly a function of the material, it
/// 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);
@ -274,3 +274,5 @@ Phase MaterialTable::game_phase(const Position& pos) {
: npm <= EndgameLimit ? PHASE_ENDGAME
: Phase(((npm - EndgameLimit) * 128) / (MidgameLimit - EndgameLimit));
}
} // namespace Material

View file

@ -25,31 +25,26 @@
#include "position.h"
#include "types.h"
const int MaterialTableSize = 8192;
namespace Material {
/// MaterialEntry is a class which contains various information about a
/// material configuration. It contains a material balance evaluation,
/// a function pointer to a special endgame evaluation function (which in
/// most cases is NULL, meaning that the standard evaluation function will
/// be used), and "scale factors" for black and white.
/// Material::Entry contains various information about a material configuration.
/// It contains a material balance evaluation, a function pointer to a special
/// endgame evaluation function (which in most cases is NULL, meaning that the
/// standard evaluation function will be used), and "scale factors".
///
/// 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
/// of 4, which will result in scores of absolute value less than one pawn.
class MaterialEntry {
struct Entry {
friend struct MaterialTable;
public:
Score material_value() const;
Score material_value() const { return make_score(value, value); }
int space_weight() const { return spaceWeight; }
Phase game_phase() const { return gamePhase; }
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;
int space_weight() const;
Phase game_phase() const;
bool specialized_eval_exists() const;
Value evaluate(const Position& pos) const;
private:
Key key;
int16_t value;
uint8_t factor[COLOR_NB];
@ -59,55 +54,24 @@ private:
Phase gamePhase;
};
typedef HashTable<Entry, 8192> Table;
/// The MaterialTable class represents a material hash table. The most important
/// method is probe(), which returns a pointer to a MaterialEntry object.
Entry* probe(const Position& pos, Table& entries, Endgames& endgames);
Phase game_phase(const Position& pos);
struct MaterialTable {
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
/// Material::scale_factor takes a position and a color as input, and
/// 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
/// 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
/// 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 ScaleFactor(factor[c]);
ScaleFactor sf = (*scalingFunction[c])(pos);
return sf == SCALE_FACTOR_NONE ? ScaleFactor(factor[c]) : sf;
return !scalingFunction[c] || (*scalingFunction[c])(pos) == SCALE_FACTOR_NONE
? ScaleFactor(factor[c]) : (*scalingFunction[c])(pos);
}
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)

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((char*)thisThread->pawnTable.entries[st->pawnKey]);
prefetch((char*)thisThread->materialTable.entries[st->materialKey]);
prefetch((char*)thisThread->materialTable[st->materialKey]);
// Update incremental scores
st->psqScore += psq_delta(piece, from, to);

View file

@ -208,7 +208,7 @@ void Search::think() {
if (Options["Contempt Factor"] && !Options["UCI_AnalyseMode"])
{
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);
}

View file

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