mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 07:27:46 +00:00
Add more output to endgame stats.
This commit is contained in:
+67
-11
@@ -980,7 +980,7 @@ namespace Stockfish::Tools::Stats
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_entry(const Position& pos, const Move&, const PackedSfenValue&) override
|
void on_entry(const Position& pos, const Move&, const PackedSfenValue& psv) override
|
||||||
{
|
{
|
||||||
const int piece_count = pos.count<ALL_PIECES>();
|
const int piece_count = pos.count<ALL_PIECES>();
|
||||||
if (piece_count > MaxManCount)
|
if (piece_count > MaxManCount)
|
||||||
@@ -989,12 +989,29 @@ namespace Stockfish::Tools::Stats
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto index = get_material_key_for_position(pos);
|
const auto index = get_material_key_for_position(pos);
|
||||||
m_counts[index] += 1;
|
auto& entry = m_entries[index];
|
||||||
|
entry.count += 1;
|
||||||
|
if (psv.game_result == 0)
|
||||||
|
{
|
||||||
|
entry.draws += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const Color winner_side = psv.game_result == 1 ? pos.side_to_move() : ~pos.side_to_move();
|
||||||
|
if (winner_side == WHITE)
|
||||||
|
{
|
||||||
|
entry.white_wins += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.black_wins += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() override
|
void reset() override
|
||||||
{
|
{
|
||||||
m_counts.clear();
|
m_entries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const std::string& get_name() const override
|
[[nodiscard]] const std::string& get_name() const override
|
||||||
@@ -1005,25 +1022,49 @@ namespace Stockfish::Tools::Stats
|
|||||||
[[nodiscard]] StatisticOutput get_output() const override
|
[[nodiscard]] StatisticOutput get_output() const override
|
||||||
{
|
{
|
||||||
StatisticOutput out;
|
StatisticOutput out;
|
||||||
auto& header = out.emplace_node<StatisticOutputEntryHeader>("Distribution of endgame configurations:");
|
auto& header = out.emplace_node<StatisticOutputEntryHeader>("Distribution of endgame configurations (count W D L Perf%):");
|
||||||
std::vector<std::pair<MaterialKey, std::uint64_t>> flattened(m_counts.begin(), m_counts.end());
|
std::vector<std::pair<MaterialKey, Entry>> flattened(m_entries.begin(), m_entries.end());
|
||||||
std::sort(flattened.begin(), flattened.end(), [](const auto& lhs, const auto& rhs) { return lhs.second > rhs.second; });
|
std::sort(flattened.begin(), flattened.end(), [](const auto& lhs, const auto& rhs) { return lhs.second.count > rhs.second.count; });
|
||||||
for (auto&& [index, count] : flattened)
|
for (auto&& [index, entry] : flattened)
|
||||||
{
|
{
|
||||||
header.emplace_child<StatisticOutputEntryValue<std::uint64_t>>(
|
header.emplace_child<StatisticOutputEntryValue<std::string>>(
|
||||||
get_padded_name_by_material_key(index),
|
get_padded_name_by_material_key(index),
|
||||||
count
|
entry.to_string()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
std::uint64_t count = 0;
|
||||||
|
std::uint64_t white_wins = 0;
|
||||||
|
std::uint64_t black_wins = 0;
|
||||||
|
std::uint64_t draws = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] std::string to_string() const
|
||||||
|
{
|
||||||
|
constexpr int wide_column_width = 9;
|
||||||
|
constexpr int narrow_column_width = 4;
|
||||||
|
|
||||||
|
const float perf =
|
||||||
|
(white_wins + draws / 2.0f)
|
||||||
|
/ (white_wins + black_wins + draws);
|
||||||
|
|
||||||
|
return
|
||||||
|
left_pad_to_length(std::to_string(count), ' ', wide_column_width) + ' '
|
||||||
|
+ left_pad_to_length(std::to_string(white_wins), ' ', wide_column_width) + ' '
|
||||||
|
+ left_pad_to_length(std::to_string(draws), ' ', wide_column_width) + ' '
|
||||||
|
+ left_pad_to_length(std::to_string(black_wins), ' ', wide_column_width) + ' '
|
||||||
|
+ left_pad_to_length(std::to_string(static_cast<int>(perf * 100.0f + 0.5f)), ' ', narrow_column_width) + '%';
|
||||||
|
}
|
||||||
|
};
|
||||||
// can support up to 17 pieces.
|
// can support up to 17 pieces.
|
||||||
// it's basically the material string encoded as a number in base 8
|
// it's basically the material string encoded as a number in base 8
|
||||||
// encoding is from the least significant digit to most significant
|
// encoding is from the least significant digit to most significant
|
||||||
// v=1, P=2, N=3, B=4, R=5, Q=6, K=7. 0 indicates end
|
// v=1, P=2, N=3, B=4, R=5, Q=6, K=7. 0 indicates end
|
||||||
std::map<MaterialKey, std::uint64_t> m_counts;
|
std::map<MaterialKey, Entry> m_entries;
|
||||||
|
|
||||||
[[nodiscard]] MaterialKey get_material_key_for_position(const Position& pos) const
|
[[nodiscard]] MaterialKey get_material_key_for_position(const Position& pos) const
|
||||||
{
|
{
|
||||||
@@ -1053,6 +1094,7 @@ namespace Stockfish::Tools::Stats
|
|||||||
[[nodiscard]] std::string get_padded_name_by_material_key(MaterialKey index) const
|
[[nodiscard]] std::string get_padded_name_by_material_key(MaterialKey index) const
|
||||||
{
|
{
|
||||||
std::string sides[COLOR_NB];
|
std::string sides[COLOR_NB];
|
||||||
|
int material[COLOR_NB] = { 0, 0 };
|
||||||
Color side = WHITE;
|
Color side = WHITE;
|
||||||
|
|
||||||
while (index != 0)
|
while (index != 0)
|
||||||
@@ -1064,18 +1106,23 @@ namespace Stockfish::Tools::Stats
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sides[side] += 'P';
|
sides[side] += 'P';
|
||||||
|
material[side] += 1;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
sides[side] += 'N';
|
sides[side] += 'N';
|
||||||
|
material[side] += 3;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
sides[side] += 'B';
|
sides[side] += 'B';
|
||||||
|
material[side] += 3;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
sides[side] += 'R';
|
sides[side] += 'R';
|
||||||
|
material[side] += 5;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
sides[side] += 'Q';
|
sides[side] += 'Q';
|
||||||
|
material[side] += 9;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
sides[side] += 'K';
|
sides[side] += 'K';
|
||||||
@@ -1086,10 +1133,19 @@ namespace Stockfish::Tools::Stats
|
|||||||
index >>= 3;
|
index >>= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int imbalance = material[WHITE] - material[BLACK];
|
||||||
|
const std::string imbalance_str =
|
||||||
|
std::string(imbalance > 0 ? "+" : "") // force + sign for positive values
|
||||||
|
+ std::string(imbalance == 0 ? " " : "") // pad 0
|
||||||
|
+ std::to_string(imbalance);
|
||||||
|
|
||||||
return
|
return
|
||||||
right_pad_to_length(sides[WHITE], ' ', MaxManCount-1)
|
right_pad_to_length(sides[WHITE], ' ', MaxManCount-1)
|
||||||
+ 'v'
|
+ 'v'
|
||||||
+ right_pad_to_length(sides[BLACK], ' ', MaxManCount-1);
|
+ right_pad_to_length(sides[BLACK], ' ', MaxManCount-1)
|
||||||
|
+ " ("
|
||||||
|
+ right_pad_to_length(imbalance_str, ' ', 3)
|
||||||
|
+ ')';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user