add damage statistics for the current turn...

...and show it in the statistics window
This commit is contained in:
uso 2008-01-11 02:31:03 +00:00
parent b28effc1e8
commit 1a8b179a51
5 changed files with 106 additions and 41 deletions

View file

@ -35,6 +35,7 @@ Version 1.3.13+svn:
* the apple key works as shortcut modifier again (bug #10586)
* made "Show lobby joins of friends only" the default preference
* new menu option added to save replays manually
* show damage statistics for the current turn in the statistics window
* WML engine:
* new tag [filter_vision] for Standard Unit Filter
* it is now possible to play [sound] repeatedly using a "repeat" attribute

View file

@ -175,7 +175,6 @@ team_num_(team), unit_count_(5,0)
str << _("Recruits") << COLUMN_SEPARATOR << n;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats_.recalls);
@ -183,16 +182,13 @@ team_num_(team), unit_count_(5,0)
str << _("Recalls") << COLUMN_SEPARATOR << n;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats_.advanced_to);
unit_count_[2] = n;
str << font::BOLD_TEXT << _("Advancements") << COLUMN_SEPARATOR
<< font::BOLD_TEXT << n;
str << _("Advancements") << COLUMN_SEPARATOR << n;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats_.deaths);
@ -200,7 +196,6 @@ team_num_(team), unit_count_(5,0)
str << _("Losses") << COLUMN_SEPARATOR << n;
items.push_back(str.str());
}
{
std::stringstream str;
n = statistics::sum_str_int_map(stats_.killed);
@ -208,31 +203,58 @@ team_num_(team), unit_count_(5,0)
str << _("Kills") << COLUMN_SEPARATOR << n;
items.push_back(str.str());
}
items.push_back("");
{
std::stringstream str;
str << font::BOLD_TEXT << _("Damage Inflicted") << COLUMN_SEPARATOR
<< font::BOLD_TEXT << stats_.damage_inflicted;
str << font::BOLD_TEXT << _("Damage")
<< COLUMN_SEPARATOR << _("Over All") << COLUMN_SEPARATOR
<< COLUMN_SEPARATOR << _("This Turn");
items.push_back(str.str());
}
{
const int dsa = 100 * stats_.damage_inflicted
- stats_.expected_damage_inflicted;
const int dst = 100 * stats_.turn_damage_inflicted
- stats_.turn_expected_damage_inflicted;
std::stringstream str;
str << _("Damage Taken") << COLUMN_SEPARATOR << stats_.damage_taken;
str << _("Inflicted") << COLUMN_SEPARATOR
<< stats_.damage_inflicted << " / "
<< (stats_.expected_damage_inflicted / 100.0)
<< COLUMN_SEPARATOR
<< ((dsa > 0) ? "+" : "")
<< ((stats_.expected_damage_inflicted == 0) ? 0
: 100 * dsa / stats_.expected_damage_inflicted)
<< "%" << COLUMN_SEPARATOR
<< stats_.turn_damage_inflicted << " / "
<< (stats_.turn_expected_damage_inflicted / 100.0)
<< COLUMN_SEPARATOR
<< ((dst > 0) ? "+" : "")
<< ((stats_.turn_expected_damage_inflicted == 0) ? 0
: 100 * dst / stats_.turn_expected_damage_inflicted)
<< "%";
items.push_back(str.str());
}
{
const int dsa = 100 * stats_.damage_taken
- stats_.expected_damage_taken;
const int dst = 100 * stats_.turn_damage_taken
- stats_.turn_expected_damage_taken;
std::stringstream str;
str << font::BOLD_TEXT << _("Damage Inflicted (EV)") << COLUMN_SEPARATOR
<< font::BOLD_TEXT << (stats_.expected_damage_inflicted / 100.0);
items.push_back(str.str());
}
{
std::stringstream str;
str << _("Damage Taken (EV)") << COLUMN_SEPARATOR
<< (stats_.expected_damage_taken / 100.0);
str << _("Taken") << COLUMN_SEPARATOR
<< stats_.damage_taken << " / "
<< (stats_.expected_damage_taken / 100.0)
<< COLUMN_SEPARATOR
<< ((dsa > 0) ? "+" : "")
<< ((stats_.expected_damage_taken == 0) ? 0
: 100 * dsa / stats_.expected_damage_taken)
<< "%" << COLUMN_SEPARATOR
<< stats_.turn_damage_taken << " / "
<< (stats_.turn_expected_damage_taken / 100.0)
<< COLUMN_SEPARATOR
<< ((dst > 0) ? "+" : "")
<< ((stats_.turn_expected_damage_taken == 0) ? 0
: 100 * dst / stats_.turn_expected_damage_taken)
<< "%";
items.push_back(str.str());
}
set_menu(items);

View file

@ -549,6 +549,8 @@ void playsingle_controller::before_human_turn(bool save)
gui_->draw();
gui_->update_display();
statistics::reset_turn_stats(player_number_);
if (save) {
menu_handler_.autosave(gamestate_.label, status_.turn(), gamestate_.starting_pos);
}

View file

@ -198,16 +198,25 @@ static void merge_stats(stats& a, const stats& b)
a.recruit_cost += b.recruit_cost;
a.recall_cost += b.recall_cost;
a.damage_inflicted += b.damage_inflicted;
a.damage_taken += b.damage_taken;
a.expected_damage_inflicted += b.expected_damage_inflicted;
a.expected_damage_taken += b.expected_damage_taken;
a.turn_damage_inflicted += b.turn_damage_inflicted;
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;
}
namespace statistics
{
stats::stats() : recruit_cost(0), recall_cost(0), damage_inflicted(0), damage_taken(0), expected_damage_inflicted(0), expected_damage_taken(0)
stats::stats() : recruit_cost(0), recall_cost(0),
damage_inflicted(0), damage_taken(0),
turn_damage_inflicted(0), turn_damage_taken(0),
expected_damage_inflicted(0), expected_damage_taken(0),
turn_expected_damage_inflicted(0), turn_expected_damage_taken(0)
{}
stats::stats(const config& cfg)
@ -229,22 +238,27 @@ config stats::write() const
char buf[50];
snprintf(buf,sizeof(buf),"%d",recruit_cost);
res["recruit_cost"] = buf;
snprintf(buf,sizeof(buf),"%d",recall_cost);
res["recall_cost"] = buf;
snprintf(buf,sizeof(buf),"%d",damage_inflicted);
res["damage_inflicted"] = buf;
snprintf(buf,sizeof(buf),"%d",damage_taken);
res["damage_taken"] = buf;
snprintf(buf,sizeof(buf),"%d",expected_damage_inflicted);
res["expected_damage_inflicted"] = buf;
snprintf(buf,sizeof(buf),"%d",expected_damage_taken);
res["expected_damage_taken"] = buf;
snprintf(buf,sizeof(buf),"%d",turn_damage_inflicted);
res["turn_damage_inflicted"] = buf;
snprintf(buf,sizeof(buf),"%d",turn_damage_taken);
res["turn_damage_taken"] = buf;
snprintf(buf,sizeof(buf),"%d",turn_expected_damage_inflicted);
res["turn_expected_damage_inflicted"] = buf;
snprintf(buf,sizeof(buf),"%d",turn_expected_damage_taken);
res["turn_expected_damage_taken"] = buf;
return res;
}
@ -275,21 +289,26 @@ void stats::write(config_writer &out) const
char buf[50];
snprintf(buf,sizeof(buf),"%d",recruit_cost);
out.write_key_val("recruit_cost", buf);
snprintf(buf,sizeof(buf),"%d",recall_cost);
out.write_key_val("recall_cost", buf);
snprintf(buf,sizeof(buf),"%d",damage_inflicted);
out.write_key_val("damage_inflicted", buf);
snprintf(buf,sizeof(buf),"%d",damage_taken);
out.write_key_val("damage_taken", buf);
snprintf(buf,sizeof(buf),"%d",expected_damage_inflicted);
out.write_key_val("expected_damage_inflicted", buf);
snprintf(buf,sizeof(buf),"%d",expected_damage_taken);
out.write_key_val("expected_damage_taken", buf);
snprintf(buf,sizeof(buf),"%d",turn_damage_inflicted);
out.write_key_val("turn_damage_inflicted", buf);
snprintf(buf,sizeof(buf),"%d",turn_damage_taken);
out.write_key_val("turn_damage_taken", buf);
snprintf(buf,sizeof(buf),"%d",turn_expected_damage_inflicted);
out.write_key_val("turn_expected_damage_inflicted", buf);
snprintf(buf,sizeof(buf),"%d",turn_expected_damage_taken);
out.write_key_val("turn_expected_damage_taken", buf);
}
void stats::read(const config& cfg)
@ -297,41 +316,40 @@ void stats::read(const config& cfg)
if(cfg.child("recruits")) {
recruits = read_str_int_map(*cfg.child("recruits"));
}
if(cfg.child("recalls")) {
recalls = read_str_int_map(*cfg.child("recalls"));
}
if(cfg.child("advances")) {
advanced_to = read_str_int_map(*cfg.child("advances"));
}
if(cfg.child("deaths")) {
deaths = read_str_int_map(*cfg.child("deaths"));
}
if(cfg.child("killed")) {
killed = read_str_int_map(*cfg.child("killed"));
}
if(cfg.child("recalls")) {
recalls = read_str_int_map(*cfg.child("recalls"));
}
if(cfg.child("attacks")) {
attacks = read_battle_result_map(*cfg.child("attacks"));
}
if(cfg.child("defends")) {
defends = read_battle_result_map(*cfg.child("defends"));
}
recruit_cost = atoi(cfg["recruit_cost"].c_str());
recall_cost = atoi(cfg["recall_cost"].c_str());
damage_inflicted = atoi(cfg["damage_inflicted"].c_str());
damage_taken = atoi(cfg["damage_taken"].c_str());
expected_damage_inflicted = atoi(cfg["expected_damage_inflicted"].c_str());
expected_damage_taken = atoi(cfg["expected_damage_taken"].c_str());
turn_damage_inflicted = atoi(cfg["turn_damage_inflicted"].c_str());
turn_damage_taken = atoi(cfg["turn_damage_taken"].c_str());
turn_expected_damage_inflicted = atoi(cfg["turn_expected_damage_inflicted"].c_str());
turn_expected_damage_taken = atoi(cfg["turn_expected_damage_taken"].c_str());
}
disabler::disabler() { stats_disabled++; }
@ -390,9 +408,14 @@ void attack_context::attack_result(attack_context::ATTACK_RESULT res, int damage
if(res != MISSES) {
attacker_stats().damage_inflicted += damage;
defender_stats().damage_taken += damage;
attacker_stats().turn_damage_inflicted += damage;
defender_stats().turn_damage_taken += damage;
}
attacker_stats().expected_damage_inflicted += damage * chance_to_hit_defender;
defender_stats().expected_damage_taken += damage * chance_to_hit_defender;
const int exp_damage = damage * chance_to_hit_defender;
attacker_stats().expected_damage_inflicted += exp_damage;
defender_stats().expected_damage_taken += exp_damage;
attacker_stats().turn_expected_damage_inflicted += exp_damage;
defender_stats().turn_expected_damage_taken += exp_damage;
if(res == KILLS) {
attacker_stats().killed[defender_type]++;
@ -410,9 +433,14 @@ void attack_context::defend_result(attack_context::ATTACK_RESULT res, int damage
if(res != MISSES) {
attacker_stats().damage_taken += damage;
defender_stats().damage_inflicted += damage;
attacker_stats().turn_damage_taken += damage;
defender_stats().turn_damage_inflicted += damage;
}
attacker_stats().expected_damage_taken += damage * chance_to_hit_attacker;
defender_stats().expected_damage_inflicted += damage * chance_to_hit_attacker;
const int exp_damage = damage * chance_to_hit_attacker;
attacker_stats().expected_damage_taken += exp_damage;
defender_stats().expected_damage_inflicted += exp_damage;
attacker_stats().turn_expected_damage_taken += exp_damage;
defender_stats().turn_expected_damage_inflicted += exp_damage;
if(res == KILLS) {
attacker_stats().deaths[attacker_type]++;
@ -470,6 +498,15 @@ void advance_unit(const unit& u)
s.advanced_to[u.id()]++;
}
void reset_turn_stats(int side)
{
stats &s = get_stats(side);
s.turn_damage_inflicted = 0;
s.turn_damage_taken = 0;
s.turn_expected_damage_inflicted = 0;
s.turn_expected_damage_taken = 0;
}
stats calculate_stats(int category, int side)
{
if(category == 0) {

View file

@ -51,6 +51,7 @@ namespace statistics
battle_result_map attacks, defends;
int damage_inflicted, damage_taken;
int turn_damage_inflicted, turn_damage_taken;
// Expected value for damage inflicted/taken * 100, based on
// probability to hit,
@ -59,6 +60,7 @@ namespace statistics
// Also, slow isn't accounted for properly.
// Rusty's simulator could be used obtain valid values.
int expected_damage_inflicted, expected_damage_taken;
int turn_expected_damage_inflicted, turn_expected_damage_taken;
};
int sum_str_int_map(const stats::str_int_map& m);
@ -110,6 +112,7 @@ namespace statistics
void fresh_stats();
void clear_current_scenario();
void reset_turn_stats(int side);
stats calculate_stats(int category, int side);
} // end namespace statistics