mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 16:53:09 +00:00
Rename Materials and Pawns hash stuff
No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
d84865eac3
commit
304deb5e83
8 changed files with 97 additions and 111 deletions
|
@ -36,8 +36,8 @@ namespace {
|
||||||
struct EvalInfo {
|
struct EvalInfo {
|
||||||
|
|
||||||
// Pointers to material and pawn hash table entries
|
// Pointers to material and pawn hash table entries
|
||||||
MaterialInfo* mi;
|
MaterialEntry* mi;
|
||||||
PawnInfo* pi;
|
PawnEntry* pi;
|
||||||
|
|
||||||
// attackedBy[color][piece type] is a bitboard representing all squares
|
// attackedBy[color][piece type] is a bitboard representing all squares
|
||||||
// attacked by a given color and piece type, attackedBy[color][0] contains
|
// attacked by a given color and piece type, attackedBy[color][0] contains
|
||||||
|
@ -250,8 +250,7 @@ namespace {
|
||||||
|
|
||||||
Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei);
|
Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei);
|
||||||
|
|
||||||
inline Score apply_weight(Score v, Score weight);
|
Value interpolate(const Score& v, Phase ph, ScaleFactor sf);
|
||||||
Value scale_by_game_phase(const Score& v, Phase ph, ScaleFactor sf);
|
|
||||||
Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight);
|
Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight);
|
||||||
double to_cp(Value v);
|
double to_cp(Value v);
|
||||||
void trace_add(int idx, Score term_w, Score term_b = SCORE_ZERO);
|
void trace_add(int idx, Score term_w, Score term_b = SCORE_ZERO);
|
||||||
|
@ -372,7 +371,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
|
||||||
margins[WHITE] = margins[BLACK] = VALUE_ZERO;
|
margins[WHITE] = margins[BLACK] = VALUE_ZERO;
|
||||||
|
|
||||||
// Probe the material hash table
|
// Probe the material hash table
|
||||||
ei.mi = Threads[pos.thread()].materialTable.material_info(pos);
|
ei.mi = Threads[pos.thread()].materialTable.probe(pos);
|
||||||
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
|
||||||
|
@ -384,7 +383,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probe the pawn hash table
|
// Probe the pawn hash table
|
||||||
ei.pi = Threads[pos.thread()].pawnTable.pawn_info(pos);
|
ei.pi = Threads[pos.thread()].pawnTable.probe(pos);
|
||||||
score += ei.pi->pawns_value();
|
score += ei.pi->pawns_value();
|
||||||
|
|
||||||
// Initialize attack and king safety bitboards
|
// Initialize attack and king safety bitboards
|
||||||
|
@ -446,9 +445,8 @@ Value do_evaluate(const Position& pos, Value& margin) {
|
||||||
sf = ScaleFactor(50);
|
sf = ScaleFactor(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpolate between the middle game and the endgame score
|
|
||||||
margin = margins[pos.side_to_move()];
|
margin = margins[pos.side_to_move()];
|
||||||
Value v = scale_by_game_phase(score, ei.mi->game_phase(), sf);
|
Value v = interpolate(score, ei.mi->game_phase(), sf);
|
||||||
|
|
||||||
// In case of tracing add all single evaluation contributions for both white and black
|
// In case of tracing add all single evaluation contributions for both white and black
|
||||||
if (Trace)
|
if (Trace)
|
||||||
|
@ -1140,18 +1138,10 @@ Value do_evaluate(const Position& pos, Value& margin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// apply_weight() applies an evaluation weight to a value trying to prevent overflow
|
// interpolate() interpolates between a middle game and an endgame score,
|
||||||
|
|
||||||
inline Score apply_weight(Score v, Score w) {
|
|
||||||
return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
|
|
||||||
(int(eg_value(v)) * eg_value(w)) / 0x100);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// scale_by_game_phase() interpolates between a middle game and an endgame score,
|
|
||||||
// based on game phase. It also scales the return value by a ScaleFactor array.
|
// based on game phase. It also scales the return value by a ScaleFactor array.
|
||||||
|
|
||||||
Value scale_by_game_phase(const Score& v, Phase ph, ScaleFactor sf) {
|
Value interpolate(const Score& v, Phase ph, ScaleFactor sf) {
|
||||||
|
|
||||||
assert(mg_value(v) > -VALUE_INFINITE && mg_value(v) < VALUE_INFINITE);
|
assert(mg_value(v) > -VALUE_INFINITE && mg_value(v) < VALUE_INFINITE);
|
||||||
assert(eg_value(v) > -VALUE_INFINITE && eg_value(v) < VALUE_INFINITE);
|
assert(eg_value(v) > -VALUE_INFINITE && eg_value(v) < VALUE_INFINITE);
|
||||||
|
|
|
@ -84,16 +84,15 @@ namespace {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
/// MaterialInfoTable::material_info() takes a position object as input,
|
/// MaterialTable::probe() takes a position object as input, looks up a MaterialEntry
|
||||||
/// computes or looks up a MaterialInfo object, and returns a pointer to it.
|
/// object, and returns a pointer to it. If the material configuration is not
|
||||||
/// If the material configuration is not already present in the table, it
|
/// already present in the table, it is computed and stored there, so we don't
|
||||||
/// is stored there, so we don't have to recompute everything when the
|
/// have to recompute everything when the same material configuration occurs again.
|
||||||
/// same material configuration occurs again.
|
|
||||||
|
|
||||||
MaterialInfo* MaterialInfoTable::material_info(const Position& pos) const {
|
MaterialEntry* MaterialTable::probe(const Position& pos) const {
|
||||||
|
|
||||||
Key key = pos.material_key();
|
Key key = pos.material_key();
|
||||||
MaterialInfo* mi = probe(key);
|
MaterialEntry* mi = Base::probe(key);
|
||||||
|
|
||||||
// If mi->key matches the position's material hash key, it means that we
|
// If mi->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
|
||||||
|
@ -101,13 +100,10 @@ MaterialInfo* MaterialInfoTable::material_info(const Position& pos) const {
|
||||||
if (mi->key == key)
|
if (mi->key == key)
|
||||||
return mi;
|
return mi;
|
||||||
|
|
||||||
// Initialize MaterialInfo entry
|
memset(mi, 0, sizeof(MaterialEntry));
|
||||||
memset(mi, 0, sizeof(MaterialInfo));
|
|
||||||
mi->key = key;
|
mi->key = key;
|
||||||
mi->factor[WHITE] = mi->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
|
mi->factor[WHITE] = mi->factor[BLACK] = (uint8_t)SCALE_FACTOR_NORMAL;
|
||||||
|
mi->gamePhase = MaterialTable::game_phase(pos);
|
||||||
// Store game phase
|
|
||||||
mi->gamePhase = MaterialInfoTable::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
|
||||||
|
@ -230,11 +226,11 @@ MaterialInfo* MaterialInfoTable::material_info(const Position& pos) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// MaterialInfoTable::imbalance() calculates imbalance comparing piece count of each
|
/// MaterialTable::imbalance() calculates imbalance comparing piece count of each
|
||||||
/// piece type for both colors.
|
/// piece type for both colors.
|
||||||
|
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
int MaterialInfoTable::imbalance(const int pieceCount[][8]) {
|
int MaterialTable::imbalance(const int pieceCount[][8]) {
|
||||||
|
|
||||||
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
|
|
||||||
|
@ -266,11 +262,11 @@ int MaterialInfoTable::imbalance(const int pieceCount[][8]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// MaterialInfoTable::game_phase() calculates the phase given the current
|
/// 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 MaterialInfo.
|
/// is stored in MaterialEntry.
|
||||||
|
|
||||||
Phase MaterialInfoTable::game_phase(const Position& pos) {
|
Phase MaterialTable::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);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ enum Phase {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// MaterialInfo is a class which contains various information about a
|
/// MaterialEntry is a class which contains various information about a
|
||||||
/// material configuration. It contains a material balance evaluation,
|
/// material configuration. It contains a material balance evaluation,
|
||||||
/// a function pointer to a special endgame evaluation function (which in
|
/// a function pointer to a special endgame evaluation function (which in
|
||||||
/// most cases is NULL, meaning that the standard evaluation function will
|
/// most cases is NULL, meaning that the standard evaluation function will
|
||||||
|
@ -44,9 +44,9 @@ enum Phase {
|
||||||
/// 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 MaterialInfo {
|
class MaterialEntry {
|
||||||
|
|
||||||
friend class MaterialInfoTable;
|
friend class MaterialTable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Score material_value() const;
|
Score material_value() const;
|
||||||
|
@ -67,15 +67,15 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// The MaterialInfoTable class represents a pawn hash table. The most important
|
/// The MaterialTable class represents a material hash table. The most important
|
||||||
/// method is material_info(), which returns a pointer to a MaterialInfo object.
|
/// method is probe(), which returns a pointer to a MaterialEntry object.
|
||||||
|
|
||||||
class MaterialInfoTable : public SimpleHash<MaterialInfo, MaterialTableSize> {
|
class MaterialTable : public HashTable<MaterialEntry, MaterialTableSize> {
|
||||||
public:
|
public:
|
||||||
MaterialInfoTable() : funcs(new Endgames()) {}
|
MaterialTable() : funcs(new Endgames()) {}
|
||||||
~MaterialInfoTable() { delete funcs; }
|
~MaterialTable() { delete funcs; }
|
||||||
|
|
||||||
MaterialInfo* material_info(const Position& pos) const;
|
MaterialEntry* probe(const Position& pos) const;
|
||||||
static Phase game_phase(const Position& pos);
|
static Phase game_phase(const Position& pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -86,14 +86,14 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// MaterialInfo::scale_factor takes a position and a color as input, and
|
/// 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 MaterialInfo::scale_factor(const Position& pos, Color c) const {
|
inline ScaleFactor MaterialEntry::scale_factor(const Position& pos, Color c) const {
|
||||||
|
|
||||||
if (!scalingFunction[c])
|
if (!scalingFunction[c])
|
||||||
return ScaleFactor(factor[c]);
|
return ScaleFactor(factor[c]);
|
||||||
|
@ -102,23 +102,23 @@ inline ScaleFactor MaterialInfo::scale_factor(const Position& pos, Color c) cons
|
||||||
return sf == SCALE_FACTOR_NONE ? ScaleFactor(factor[c]) : sf;
|
return sf == SCALE_FACTOR_NONE ? ScaleFactor(factor[c]) : sf;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Value MaterialInfo::evaluate(const Position& pos) const {
|
inline Value MaterialEntry::evaluate(const Position& pos) const {
|
||||||
return (*evaluationFunction)(pos);
|
return (*evaluationFunction)(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Score MaterialInfo::material_value() const {
|
inline Score MaterialEntry::material_value() const {
|
||||||
return make_score(value, value);
|
return make_score(value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int MaterialInfo::space_weight() const {
|
inline int MaterialEntry::space_weight() const {
|
||||||
return spaceWeight;
|
return spaceWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Phase MaterialInfo::game_phase() const {
|
inline Phase MaterialEntry::game_phase() const {
|
||||||
return gamePhase;
|
return gamePhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool MaterialInfo::specialized_eval_exists() const {
|
inline bool MaterialEntry::specialized_eval_exists() const {
|
||||||
return evaluationFunction != NULL;
|
return evaluationFunction != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,23 +80,18 @@ namespace {
|
||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
inline Score apply_weight(Score v, Score w) {
|
|
||||||
return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
|
|
||||||
(int(eg_value(v)) * eg_value(w)) / 0x100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// PawnInfoTable::pawn_info() takes a position object as input, computes
|
/// PawnTable::probe() takes a position object as input, computes a PawnEntry
|
||||||
/// a PawnInfo object, and returns a pointer to it. The result is also stored
|
/// object, and returns a pointer to it. The result is also stored in a hash
|
||||||
/// in an hash table, so we don't have to recompute everything when the same
|
/// table, so we don't have to recompute everything when the same pawn structure
|
||||||
/// pawn structure occurs again.
|
/// occurs again.
|
||||||
|
|
||||||
PawnInfo* PawnInfoTable::pawn_info(const Position& pos) const {
|
PawnEntry* PawnTable::probe(const Position& pos) const {
|
||||||
|
|
||||||
Key key = pos.pawn_key();
|
Key key = pos.pawn_key();
|
||||||
PawnInfo* pi = probe(key);
|
PawnEntry* pi = Base::probe(key);
|
||||||
|
|
||||||
// If pi->key matches the position's pawn hash key, it means that we
|
// If pi->key matches the position's pawn hash key, it means that we
|
||||||
// have analysed this pawn structure before, and we can simply return
|
// have analysed this pawn structure before, and we can simply return
|
||||||
|
@ -104,19 +99,16 @@ PawnInfo* PawnInfoTable::pawn_info(const Position& pos) const {
|
||||||
if (pi->key == key)
|
if (pi->key == key)
|
||||||
return pi;
|
return pi;
|
||||||
|
|
||||||
// Initialize PawnInfo entry
|
|
||||||
pi->key = key;
|
pi->key = key;
|
||||||
pi->passedPawns[WHITE] = pi->passedPawns[BLACK] = 0;
|
pi->passedPawns[WHITE] = pi->passedPawns[BLACK] = 0;
|
||||||
pi->kingSquares[WHITE] = pi->kingSquares[BLACK] = SQ_NONE;
|
pi->kingSquares[WHITE] = pi->kingSquares[BLACK] = SQ_NONE;
|
||||||
pi->halfOpenFiles[WHITE] = pi->halfOpenFiles[BLACK] = 0xFF;
|
pi->halfOpenFiles[WHITE] = pi->halfOpenFiles[BLACK] = 0xFF;
|
||||||
|
|
||||||
// Calculate pawn attacks
|
|
||||||
Bitboard wPawns = pos.pieces(PAWN, WHITE);
|
Bitboard wPawns = pos.pieces(PAWN, WHITE);
|
||||||
Bitboard bPawns = pos.pieces(PAWN, BLACK);
|
Bitboard bPawns = pos.pieces(PAWN, BLACK);
|
||||||
pi->pawnAttacks[WHITE] = ((wPawns << 9) & ~FileABB) | ((wPawns << 7) & ~FileHBB);
|
pi->pawnAttacks[WHITE] = ((wPawns & ~FileHBB) << 9) | ((wPawns & ~FileABB) << 7);
|
||||||
pi->pawnAttacks[BLACK] = ((bPawns >> 7) & ~FileABB) | ((bPawns >> 9) & ~FileHBB);
|
pi->pawnAttacks[BLACK] = ((bPawns & ~FileHBB) >> 7) | ((bPawns & ~FileABB) >> 9);
|
||||||
|
|
||||||
// Evaluate pawns for both colors and weight the result
|
|
||||||
pi->value = evaluate_pawns<WHITE>(pos, wPawns, bPawns, pi)
|
pi->value = evaluate_pawns<WHITE>(pos, wPawns, bPawns, pi)
|
||||||
- evaluate_pawns<BLACK>(pos, bPawns, wPawns, pi);
|
- evaluate_pawns<BLACK>(pos, bPawns, wPawns, pi);
|
||||||
|
|
||||||
|
@ -126,11 +118,11 @@ PawnInfo* PawnInfoTable::pawn_info(const Position& pos) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// PawnInfoTable::evaluate_pawns() evaluates each pawn of the given color
|
/// PawnTable::evaluate_pawns() evaluates each pawn of the given color
|
||||||
|
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
|
Score PawnTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
|
||||||
Bitboard theirPawns, PawnInfo* pi) {
|
Bitboard theirPawns, PawnEntry* pi) {
|
||||||
|
|
||||||
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
|
|
||||||
|
@ -158,11 +150,11 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
|
||||||
|
|
||||||
// Flag the pawn as passed, isolated, doubled or member of a pawn
|
// Flag the pawn as passed, isolated, doubled or member of a pawn
|
||||||
// chain (but not the backward one).
|
// chain (but not the backward one).
|
||||||
passed = !(theirPawns & passed_pawn_mask(Us, s));
|
chain = ourPawns & adjacent_files_bb(f) & b;
|
||||||
|
isolated = !(ourPawns & adjacent_files_bb(f));
|
||||||
doubled = ourPawns & squares_in_front_of(Us, s);
|
doubled = ourPawns & squares_in_front_of(Us, s);
|
||||||
opposed = theirPawns & squares_in_front_of(Us, s);
|
opposed = theirPawns & squares_in_front_of(Us, s);
|
||||||
isolated = !(ourPawns & adjacent_files_bb(f));
|
passed = !(theirPawns & passed_pawn_mask(Us, s));
|
||||||
chain = ourPawns & adjacent_files_bb(f) & b;
|
|
||||||
|
|
||||||
// Test for backward pawn
|
// Test for backward pawn
|
||||||
backward = false;
|
backward = false;
|
||||||
|
@ -222,15 +214,16 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
|
||||||
if (candidate)
|
if (candidate)
|
||||||
value += CandidateBonus[relative_rank(Us, s)];
|
value += CandidateBonus[relative_rank(Us, s)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// PawnInfo::shelter_storm() calculates shelter and storm penalties for the file
|
/// PawnEntry::shelter_storm() calculates shelter and storm penalties for the file
|
||||||
/// the king is on, as well as the two adjacent files.
|
/// the king is on, as well as the two adjacent files.
|
||||||
|
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
Value PawnInfo::shelter_storm(const Position& pos, Square ksq) {
|
Value PawnEntry::shelter_storm(const Position& pos, Square ksq) {
|
||||||
|
|
||||||
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
|
|
||||||
|
@ -260,16 +253,16 @@ Value PawnInfo::shelter_storm(const Position& pos, Square ksq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// PawnInfo::update_safety() calculates and caches a bonus for king safety. It is
|
/// PawnEntry::update_safety() calculates and caches a bonus for king safety. It is
|
||||||
/// called only when king square changes, about 20% of total king_safety() calls.
|
/// called only when king square changes, about 20% of total king_safety() calls.
|
||||||
|
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
Score PawnInfo::update_safety(const Position& pos, Square ksq) {
|
Score PawnEntry::update_safety(const Position& pos, Square ksq) {
|
||||||
|
|
||||||
kingSquares[Us] = ksq;
|
kingSquares[Us] = ksq;
|
||||||
|
|
||||||
if (relative_rank(Us, ksq) > RANK_4)
|
if (relative_rank(Us, ksq) > RANK_4)
|
||||||
return kingShelters[Us] = SCORE_ZERO;
|
return kingSafety[Us] = SCORE_ZERO;
|
||||||
|
|
||||||
Value bonus = shelter_storm<Us>(pos, ksq);
|
Value bonus = shelter_storm<Us>(pos, ksq);
|
||||||
|
|
||||||
|
@ -280,9 +273,9 @@ Score PawnInfo::update_safety(const Position& pos, Square ksq) {
|
||||||
if (pos.can_castle(Us == WHITE ? WHITE_OOO : BLACK_OOO))
|
if (pos.can_castle(Us == WHITE ? WHITE_OOO : BLACK_OOO))
|
||||||
bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_C1)));
|
bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_C1)));
|
||||||
|
|
||||||
return kingShelters[Us] = make_score(bonus, 0);
|
return kingSafety[Us] = make_score(bonus, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit template instantiation
|
// Explicit template instantiation
|
||||||
template Score PawnInfo::update_safety<WHITE>(const Position& pos, Square ksq);
|
template Score PawnEntry::update_safety<WHITE>(const Position& pos, Square ksq);
|
||||||
template Score PawnInfo::update_safety<BLACK>(const Position& pos, Square ksq);
|
template Score PawnEntry::update_safety<BLACK>(const Position& pos, Square ksq);
|
||||||
|
|
39
src/pawns.h
39
src/pawns.h
|
@ -26,16 +26,16 @@
|
||||||
|
|
||||||
const int PawnTableSize = 16384;
|
const int PawnTableSize = 16384;
|
||||||
|
|
||||||
/// PawnInfo is a class which contains various information about a pawn
|
/// PawnEntry is a class which contains various information about a pawn
|
||||||
/// structure. Currently, it only includes a middle game and an end game
|
/// structure. Currently, it only includes a middle game and an end game
|
||||||
/// pawn structure evaluation, and a bitboard of passed pawns. We may want
|
/// pawn structure evaluation, and a bitboard of passed pawns. We may want
|
||||||
/// to add further information in the future. A lookup to the pawn hash
|
/// to add further information in the future. A lookup to the pawn hash
|
||||||
/// table (performed by calling the pawn_info method in a PawnInfoTable
|
/// table (performed by calling the probe method in a PawnTable object)
|
||||||
/// object) returns a pointer to a PawnInfo object.
|
/// returns a pointer to a PawnEntry object.
|
||||||
|
|
||||||
class PawnInfo {
|
class PawnEntry {
|
||||||
|
|
||||||
friend class PawnInfoTable;
|
friend class PawnTable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Score pawns_value() const;
|
Score pawns_value() const;
|
||||||
|
@ -61,50 +61,51 @@ private:
|
||||||
Square kingSquares[2];
|
Square kingSquares[2];
|
||||||
Score value;
|
Score value;
|
||||||
int halfOpenFiles[2];
|
int halfOpenFiles[2];
|
||||||
Score kingShelters[2];
|
Score kingSafety[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// The PawnInfoTable class represents a pawn hash table. The most important
|
/// The PawnTable class represents a pawn hash table. The most important
|
||||||
/// method is pawn_info, which returns a pointer to a PawnInfo object.
|
/// method is probe, which returns a pointer to a PawnEntry object.
|
||||||
|
|
||||||
class PawnInfoTable : public SimpleHash<PawnInfo, PawnTableSize> {
|
class PawnTable : public HashTable<PawnEntry, PawnTableSize> {
|
||||||
public:
|
public:
|
||||||
PawnInfo* pawn_info(const Position& pos) const;
|
PawnEntry* probe(const Position& pos) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
static Score evaluate_pawns(const Position& pos, Bitboard ourPawns, Bitboard theirPawns, PawnInfo* pi);
|
static Score evaluate_pawns(const Position& pos, Bitboard ourPawns,
|
||||||
|
Bitboard theirPawns, PawnEntry* pi);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline Score PawnInfo::pawns_value() const {
|
inline Score PawnEntry::pawns_value() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Bitboard PawnInfo::pawn_attacks(Color c) const {
|
inline Bitboard PawnEntry::pawn_attacks(Color c) const {
|
||||||
return pawnAttacks[c];
|
return pawnAttacks[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Bitboard PawnInfo::passed_pawns(Color c) const {
|
inline Bitboard PawnEntry::passed_pawns(Color c) const {
|
||||||
return passedPawns[c];
|
return passedPawns[c];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int PawnInfo::file_is_half_open(Color c, File f) const {
|
inline int PawnEntry::file_is_half_open(Color c, File f) const {
|
||||||
return halfOpenFiles[c] & (1 << int(f));
|
return halfOpenFiles[c] & (1 << int(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int PawnInfo::has_open_file_to_left(Color c, File f) const {
|
inline int PawnEntry::has_open_file_to_left(Color c, File f) const {
|
||||||
return halfOpenFiles[c] & ((1 << int(f)) - 1);
|
return halfOpenFiles[c] & ((1 << int(f)) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int PawnInfo::has_open_file_to_right(Color c, File f) const {
|
inline int PawnEntry::has_open_file_to_right(Color c, File f) const {
|
||||||
return halfOpenFiles[c] & ~((1 << int(f+1)) - 1);
|
return halfOpenFiles[c] & ~((1 << int(f+1)) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
inline Score PawnInfo::king_safety(const Position& pos, Square ksq) {
|
inline Score PawnEntry::king_safety(const Position& pos, Square ksq) {
|
||||||
return kingSquares[Us] == ksq ? kingShelters[Us] : update_safety<Us>(pos, ksq);
|
return kingSquares[Us] == ksq ? kingSafety[Us] : update_safety<Us>(pos, ksq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(PAWNS_H_INCLUDED)
|
#endif // !defined(PAWNS_H_INCLUDED)
|
||||||
|
|
|
@ -85,8 +85,8 @@ public:
|
||||||
void wait_for_stop_or_ponderhit();
|
void wait_for_stop_or_ponderhit();
|
||||||
|
|
||||||
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
|
SplitPoint splitPoints[MAX_SPLITPOINTS_PER_THREAD];
|
||||||
MaterialInfoTable materialTable;
|
MaterialTable materialTable;
|
||||||
PawnInfoTable pawnTable;
|
PawnTable pawnTable;
|
||||||
int threadID;
|
int threadID;
|
||||||
int maxPly;
|
int maxPly;
|
||||||
Lock sleepLock;
|
Lock sleepLock;
|
||||||
|
@ -111,7 +111,7 @@ class ThreadsManager {
|
||||||
static storage duration are automatically set to zero before enter main()
|
static storage duration are automatically set to zero before enter main()
|
||||||
*/
|
*/
|
||||||
public:
|
public:
|
||||||
void init(); // No c'tor becuase Threads is static and we need stuff initialized
|
void init(); // No c'tor becuase Threads is static and we need engine initialized
|
||||||
~ThreadsManager();
|
~ThreadsManager();
|
||||||
|
|
||||||
Thread& operator[](int id) { return *threads[id]; }
|
Thread& operator[](int id) { return *threads[id]; }
|
||||||
|
|
16
src/tt.h
16
src/tt.h
|
@ -137,16 +137,16 @@ inline void TranspositionTable::refresh(const TTEntry* tte) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A simple fixed size hash table used to store pawns and material
|
/// A simple hash table used to store pawns and material configurations. It is
|
||||||
/// configurations. It is basically just an array of Entry objects.
|
/// basically just an array of Entry objects. Without cluster concept, overwrite
|
||||||
/// Without cluster concept, overwrite policy nor resizing.
|
/// policy nor resizing.
|
||||||
|
|
||||||
template<class Entry, int HashSize>
|
template<class Entry, int HashSize>
|
||||||
struct SimpleHash {
|
struct HashTable {
|
||||||
|
|
||||||
typedef SimpleHash<Entry, HashSize> Base;
|
typedef HashTable<Entry, HashSize> Base;
|
||||||
|
|
||||||
SimpleHash() {
|
HashTable() {
|
||||||
|
|
||||||
entries = new (std::nothrow) Entry[HashSize];
|
entries = new (std::nothrow) Entry[HashSize];
|
||||||
if (!entries)
|
if (!entries)
|
||||||
|
@ -158,12 +158,12 @@ struct SimpleHash {
|
||||||
memset(entries, 0, HashSize * sizeof(Entry));
|
memset(entries, 0, HashSize * sizeof(Entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SimpleHash() { delete [] entries; }
|
virtual ~HashTable() { delete [] entries; }
|
||||||
|
|
||||||
Entry* probe(Key key) const { return entries + ((uint32_t)key & (HashSize - 1)); }
|
Entry* probe(Key key) const { return entries + ((uint32_t)key & (HashSize - 1)); }
|
||||||
void prefetch(Key key) const { ::prefetch((char*)probe(key)); }
|
void prefetch(Key key) const { ::prefetch((char*)probe(key)); }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
Entry* entries;
|
Entry* entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -297,6 +297,12 @@ inline Score operator/(Score s, int i) {
|
||||||
return make_score(mg_value(s) / i, eg_value(s) / i);
|
return make_score(mg_value(s) / i, eg_value(s) / i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Weight score v by score w trying to prevent overflow
|
||||||
|
inline Score apply_weight(Score v, Score w) {
|
||||||
|
return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
|
||||||
|
(int(eg_value(v)) * eg_value(w)) / 0x100);
|
||||||
|
}
|
||||||
|
|
||||||
#undef ENABLE_OPERATORS_ON
|
#undef ENABLE_OPERATORS_ON
|
||||||
#undef ENABLE_SAFE_OPERATORS_ON
|
#undef ENABLE_SAFE_OPERATORS_ON
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue