Hit stats: Track current turn stats too.

This commit is contained in:
josteph 2019-05-09 12:36:39 +00:00
parent b52eb32ba2
commit 494bdc51f7
4 changed files with 59 additions and 19 deletions

View file

@ -161,22 +161,9 @@ void statistics_dialog::add_damage_row(
damage_list.add_row(data);
}
void statistics_dialog::add_hits_row(
window& window,
const std::string& type,
const std::map<int, struct statistics::stats::by_cth_t>& by_cth,
const bool show_this_turn)
// Return the string to use in the "Hits" table, showing actual and expected number of hits.
static std::string tally(const std::map<int, struct statistics::stats::by_cth_t>& by_cth)
{
listbox& hits_list = find_widget<listbox>(&window, "stats_list_hits", false);
std::map<std::string, string_map> data;
string_map item;
std::ostringstream str;
item["label"] = type;
data.emplace("hits_type", item);
int overall_hits = 0;
double expected_hits = 0;
@ -186,14 +173,32 @@ void statistics_dialog::add_hits_row(
expected_hits += (cth * 0.01) * i.second.strikes;
}
str.str("");
str << overall_hits << " / " << expected_hits;
// TODO: show a priori probability of this actual result here. https://en.wikipedia.org/wiki/Poisson_binomial_distribution
item["label"] = str.str();
std::ostringstream str;
str << overall_hits << " / " << expected_hits;
return str.str();
}
void statistics_dialog::add_hits_row(
window& window,
const std::string& type,
const std::map<int, struct statistics::stats::by_cth_t>& by_cth,
const std::map<int, struct statistics::stats::by_cth_t>& turn_by_cth,
const bool show_this_turn)
{
listbox& hits_list = find_widget<listbox>(&window, "stats_list_hits", false);
std::map<std::string, string_map> data;
string_map item;
item["label"] = type;
data.emplace("hits_type", item);
item["label"] = tally(by_cth);
data.emplace("hits_overall", item);
if(show_this_turn) {
item["label"] = "";
item["label"] = tally(turn_by_cth);
data.emplace("hits_this_turn", item);
}
@ -248,6 +253,7 @@ void statistics_dialog::update_lists(window& window)
);
add_hits_row(window, _("Inflicted"),
stats.by_cth_inflicted,
stats.turn_by_cth_inflicted,
show_this_turn
);
@ -260,6 +266,7 @@ void statistics_dialog::update_lists(window& window)
);
add_hits_row(window, _("Taken"),
stats.by_cth_taken,
stats.turn_by_cth_taken,
show_this_turn
);
}

View file

@ -60,6 +60,7 @@ private:
window& window,
const std::string& type,
const std::map<int, struct statistics::stats::by_cth_t>& by_cth,
const std::map<int, struct statistics::stats::by_cth_t>& turn_by_cth,
const bool show_this_turn);
void update_lists(window& window);

View file

@ -265,6 +265,9 @@ static void merge_stats(stats& a, const stats& b)
a.turn_damage_taken = b.turn_damage_taken;
a.turn_expected_damage_inflicted = b.turn_expected_damage_inflicted;
a.turn_expected_damage_taken = b.turn_expected_damage_taken;
a.turn_by_cth_inflicted = b.turn_by_cth_inflicted;
a.turn_by_cth_taken = b.turn_by_cth_taken;
}
namespace statistics
@ -286,6 +289,8 @@ stats::stats() :
turn_damage_taken(0),
by_cth_inflicted(),
by_cth_taken(),
turn_by_cth_inflicted(),
turn_by_cth_taken(),
expected_damage_inflicted(0),
expected_damage_taken(0),
turn_expected_damage_inflicted(0),
@ -309,6 +314,8 @@ stats::stats(const config& cfg) :
turn_damage_taken(0),
by_cth_inflicted(),
by_cth_taken(),
turn_by_cth_inflicted(),
turn_by_cth_taken(),
expected_damage_inflicted(0),
expected_damage_taken(0),
turn_expected_damage_inflicted(0),
@ -330,6 +337,8 @@ config stats::write() const
res.add_child("defends",write_battle_result_map(defends));
res.add_child("by_cth_inflicted", write_by_cth_map(by_cth_inflicted));
res.add_child("by_cth_taken", write_by_cth_map(by_cth_taken));
res.add_child("turn_by_cth_inflicted", write_by_cth_map(turn_by_cth_inflicted));
res.add_child("turn_by_cth_taken", write_by_cth_map(turn_by_cth_taken));
res["recruit_cost"] = recruit_cost;
res["recall_cost"] = recall_cost;
@ -378,6 +387,12 @@ void stats::write(config_writer &out) const
out.open_child("by_cth_taken");
out.write(write_by_cth_map(by_cth_taken));
out.close_child("by_cth_taken");
out.open_child("turn_by_cth_inflicted");
out.write(write_by_cth_map(turn_by_cth_inflicted));
out.close_child("turn_by_cth_inflicted");
out.open_child("turn_by_cth_taken");
out.write(write_by_cth_map(turn_by_cth_taken));
out.close_child("turn_by_cth_taken");
out.write_key_val("recruit_cost", recruit_cost);
out.write_key_val("recall_cost", recall_cost);
@ -427,6 +442,12 @@ void stats::read(const config& cfg)
if (const config &c = cfg.child("by_cth_taken")) {
by_cth_taken = read_by_cth_map(c);
}
if (const config &c = cfg.child("turn_by_cth_inflicted")) {
turn_by_cth_inflicted = read_by_cth_map(c);
}
if (const config &c = cfg.child("turn_by_cth_taken")) {
turn_by_cth_taken = read_by_cth_map(c);
}
recruit_cost = cfg["recruit_cost"].to_int();
recall_cost = cfg["recall_cost"].to_int();
@ -513,10 +534,14 @@ void attack_context::attack_result(hit_result res, int cth, int damage, int drai
if(res != MISSES) {
++att_stats.by_cth_inflicted[cth].hits;
++att_stats.turn_by_cth_inflicted[cth].hits;
++def_stats.by_cth_taken[cth].hits;
++def_stats.turn_by_cth_taken[cth].hits;
}
++att_stats.by_cth_inflicted[cth].strikes;
++att_stats.turn_by_cth_inflicted[cth].strikes;
++def_stats.by_cth_taken[cth].strikes;
++def_stats.turn_by_cth_taken[cth].strikes;
if(res != MISSES) {
// handle drain
@ -544,10 +569,14 @@ void attack_context::defend_result(hit_result res, int cth, int damage, int drai
if(res != MISSES) {
++def_stats.by_cth_inflicted[cth].hits;
++def_stats.turn_by_cth_inflicted[cth].hits;
++att_stats.by_cth_taken[cth].hits;
++att_stats.turn_by_cth_taken[cth].hits;
}
++def_stats.by_cth_inflicted[cth].strikes;
++def_stats.turn_by_cth_inflicted[cth].strikes;
++att_stats.by_cth_taken[cth].strikes;
++att_stats.turn_by_cth_taken[cth].strikes;
if(res != MISSES) {
//handle drain
@ -615,6 +644,8 @@ void reset_turn_stats(const std::string & save_id)
s.turn_damage_taken = 0;
s.turn_expected_damage_inflicted = 0;
s.turn_expected_damage_taken = 0;
s.turn_by_cth_inflicted.clear();
s.turn_by_cth_taken.clear();
s.save_id = save_id;
}

View file

@ -62,6 +62,7 @@ namespace statistics
};
/// Maps of chance-to-hit percentage to a 'struct by_cth_t'.
std::map<int, struct by_cth_t> by_cth_inflicted, by_cth_taken;
std::map<int, struct by_cth_t> turn_by_cth_inflicted, turn_by_cth_taken;
static const int decimal_shift = 1000;