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:
parent
52bbf372bb
commit
231f62baf7
6 changed files with 72 additions and 104 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue