statistics.cpp

Go to the documentation of this file.
00001 /* $Id: statistics.cpp 26628 2008-05-14 20:48:25Z suokko $ */
00002 /*
00003    Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file statistics.cpp
00016 //! Manage statistics: recruitments, recalls, kills, losses, etc.
00017 
00018 #include "global.hpp"
00019 #include "config.hpp"
00020 #include "statistics.hpp"
00021 #include "util.hpp"
00022 #include "log.hpp"
00023 #include "serialization/binary_or_text.hpp"
00024 #include "unit.hpp"
00025 
00026 #define ERR_NG lg::err(lg::engine)
00027 
00028 namespace {
00029 
00030 // This variable is true whenever the statistics are mid-scenario.
00031 // This means a new scenario shouldn't be added to the master stats record.
00032 bool mid_scenario = false;
00033 
00034 typedef statistics::stats stats;
00035 
00036 int stats_disabled = 0;
00037 
00038 struct scenario_stats
00039 {
00040     explicit scenario_stats(const std::string& name) : scenario_name(name)
00041     {}
00042 
00043     explicit scenario_stats(const config& cfg);
00044 
00045     config write() const;
00046     void write(config_writer &out) const;
00047 
00048     std::vector<stats> team_stats;
00049     std::string scenario_name;
00050 };
00051 
00052 scenario_stats::scenario_stats(const config& cfg)
00053 {
00054     scenario_name = cfg["scenario"];
00055     const config::child_list& teams = cfg.get_children("team");
00056     for(config::child_list::const_iterator i = teams.begin(); i != teams.end(); ++i) {
00057         team_stats.push_back(stats(**i));
00058     }
00059 }
00060 
00061 config scenario_stats::write() const
00062 {
00063     config res;
00064     res["scenario"] = scenario_name;
00065     for(std::vector<stats>::const_iterator i = team_stats.begin(); i != team_stats.end(); ++i) {
00066         res.add_child("team",i->write());
00067     }
00068 
00069     return res;
00070 }
00071 
00072 void scenario_stats::write(config_writer &out) const
00073 {
00074     out.write_key_val("scenario", scenario_name);
00075     for(std::vector<stats>::const_iterator i = team_stats.begin(); i != team_stats.end(); ++i) {
00076         out.open_child("team");
00077         i->write(out);
00078         out.close_child("team");
00079     }
00080 }
00081 
00082 std::vector<scenario_stats> master_stats;
00083 
00084 } // end anon namespace
00085 
00086 static stats& get_stats(int team)
00087 {
00088     if(master_stats.empty()) {
00089         master_stats.push_back(scenario_stats(""));
00090     }
00091 
00092     std::vector<stats>& team_stats = master_stats.back().team_stats;
00093     const size_t index = size_t(team-1);
00094     if(index >= team_stats.size()) {
00095         team_stats.resize(index+1);
00096     }
00097 
00098     return team_stats[index];
00099 }
00100 
00101 static config write_str_int_map(const stats::str_int_map& m)
00102 {
00103     config res;
00104     for(stats::str_int_map::const_iterator i = m.begin(); i != m.end(); ++i) {
00105         char buf[50];
00106         snprintf(buf,sizeof(buf),"%d",i->second);
00107         res[i->first] = buf;
00108     }
00109 
00110     return res;
00111 }
00112 
00113 static void write_str_int_map(config_writer &out, const stats::str_int_map& m)
00114 {
00115     for(stats::str_int_map::const_iterator i = m.begin(); i != m.end(); ++i) {
00116         char buf[50];
00117         snprintf(buf,sizeof(buf),"%d",i->second);
00118         out.write_key_val(i->first, buf);
00119     }
00120 }
00121 
00122 static stats::str_int_map read_str_int_map(const config& cfg)
00123 {
00124     stats::str_int_map m;
00125     for(string_map::const_iterator i = cfg.values.begin(); i != cfg.values.end(); ++i) {
00126         m[i->first] = atoi(i->second.c_str());
00127     }
00128 
00129     return m;
00130 }
00131 
00132 static config write_battle_result_map(const stats::battle_result_map& m)
00133 {
00134     config res;
00135     for(stats::battle_result_map::const_iterator i = m.begin(); i != m.end(); ++i) {
00136         config& new_cfg = res.add_child("sequence");
00137         new_cfg = write_str_int_map(i->second);
00138 
00139         char buf[50];
00140         snprintf(buf,sizeof(buf),"%d",i->first);
00141         new_cfg["_num"] = buf;
00142     }
00143 
00144     return res;
00145 }
00146 
00147 static void write_battle_result_map(config_writer &out, const stats::battle_result_map& m)
00148 {
00149     for(stats::battle_result_map::const_iterator i = m.begin(); i != m.end(); ++i) {
00150         out.open_child("sequence");
00151         write_str_int_map(out, i->second);
00152 
00153         char buf[50];
00154         snprintf(buf,sizeof(buf),"%d",i->first);
00155         out.write_key_val("_num", buf);
00156         out.close_child("sequence");
00157     }
00158 }
00159 
00160 static stats::battle_result_map read_battle_result_map(const config& cfg)
00161 {
00162     stats::battle_result_map m;
00163     const config::child_list c = cfg.get_children("sequence");
00164     for(config::child_list::const_iterator i = c.begin(); i != c.end(); ++i) {
00165         config item = **i;
00166         const int key = atoi(item["_num"].c_str());
00167         item.values.erase("_num");
00168         m[key] = read_str_int_map(item);
00169     }
00170 
00171     return m;
00172 }
00173 
00174 static void merge_str_int_map(stats::str_int_map& a, const stats::str_int_map& b)
00175 {
00176     for(stats::str_int_map::const_iterator i = b.begin(); i != b.end(); ++i) {
00177         a[i->first] += i->second;
00178     }
00179 }
00180 
00181 static void merge_battle_result_maps(stats::battle_result_map& a, const stats::battle_result_map& b)
00182 {
00183     for(stats::battle_result_map::const_iterator i = b.begin(); i != b.end(); ++i) {
00184         merge_str_int_map(a[i->first],i->second);
00185     }
00186 }
00187 
00188 static void merge_stats(stats& a, const stats& b)
00189 {
00190     merge_str_int_map(a.recruits,b.recruits);
00191     merge_str_int_map(a.recalls,b.recalls);
00192     merge_str_int_map(a.advanced_to,b.advanced_to);
00193     merge_str_int_map(a.deaths,b.deaths);
00194     merge_str_int_map(a.killed,b.killed);
00195 
00196     merge_battle_result_maps(a.attacks,b.attacks);
00197     merge_battle_result_maps(a.defends,b.defends);
00198 
00199     a.recruit_cost += b.recruit_cost;
00200     a.recall_cost += b.recall_cost;
00201 
00202     a.damage_inflicted += b.damage_inflicted;
00203     a.damage_taken += b.damage_taken;
00204     a.expected_damage_inflicted += b.expected_damage_inflicted;
00205     a.expected_damage_taken += b.expected_damage_taken;
00206     a.turn_damage_inflicted += b.turn_damage_inflicted;
00207     a.turn_damage_taken += b.turn_damage_taken;
00208     a.turn_expected_damage_inflicted += b.turn_expected_damage_inflicted;
00209     a.turn_expected_damage_taken += b.turn_expected_damage_taken;
00210     
00211     a.new_expected_damage_inflicted += b.new_expected_damage_inflicted;
00212     a.new_expected_damage_taken += b.new_expected_damage_taken;
00213     a.new_turn_expected_damage_inflicted += b.new_turn_expected_damage_inflicted;
00214     a.new_turn_expected_damage_taken += b.new_turn_expected_damage_taken;
00215 }
00216 
00217 namespace statistics
00218 {
00219 
00220 stats::stats() : recruit_cost(0), recall_cost(0),
00221                  damage_inflicted(0), damage_taken(0),
00222                  turn_damage_inflicted(0), turn_damage_taken(0),
00223                  expected_damage_inflicted(0), expected_damage_taken(0),
00224                  turn_expected_damage_inflicted(0), turn_expected_damage_taken(0),
00225                  new_expected_damage_inflicted(0), new_expected_damage_taken(0),
00226                  new_turn_expected_damage_inflicted(0), new_turn_expected_damage_taken(0)
00227 {}
00228 
00229 stats::stats(const config& cfg)
00230 {
00231     read(cfg);
00232 }
00233 
00234 config stats::write() const
00235 {
00236     config res;
00237     res.add_child("recruits",write_str_int_map(recruits));
00238     res.add_child("recalls",write_str_int_map(recalls));
00239     res.add_child("advances",write_str_int_map(advanced_to));
00240     res.add_child("deaths",write_str_int_map(deaths));
00241     res.add_child("killed",write_str_int_map(killed));
00242     res.add_child("attacks",write_battle_result_map(attacks));
00243     res.add_child("defends",write_battle_result_map(defends));
00244 
00245     std::stringstream ss;   
00246     ss << recruit_cost;
00247     res["recruit_cost"] = ss.str();
00248     ss.str(std::string());
00249     ss << recall_cost;
00250     res["recall_cost"] = ss.str();
00251 
00252     ss.str(std::string());
00253     ss << damage_inflicted;
00254     res["damage_inflicted"] = ss.str();
00255     ss.str(std::string());
00256     ss << damage_taken;
00257     res["damage_taken"] = ss.str();
00258     ss.str(std::string());
00259     ss << expected_damage_inflicted;
00260     res["expected_damage_inflicted"] = ss.str();
00261     ss.str(std::string());
00262     ss << expected_damage_taken;
00263     res["expected_damage_taken"] = ss.str();
00264     ss.str(std::string());
00265     ss << turn_damage_inflicted;
00266 
00267     res["turn_damage_inflicted"] = ss.str();
00268     ss.str(std::string());
00269     ss << turn_damage_taken;
00270     res["turn_damage_taken"] = ss.str();
00271     ss.str(std::string());
00272     ss << turn_expected_damage_inflicted;
00273     res["turn_expected_damage_inflicted"] = ss.str();
00274     ss.str(std::string());
00275     ss << turn_expected_damage_taken;
00276     res["turn_expected_damage_taken"] = ss.str();
00277 
00278     ss.str(std::string());
00279     ss << new_expected_damage_inflicted;
00280     res["new_expected_damage_inflicted"] = ss.str();
00281     ss.str(std::string());
00282     ss << new_expected_damage_taken;
00283     res["new_expected_damage_taken"] = ss.str();
00284     ss.str(std::string());
00285     ss << new_turn_expected_damage_inflicted;
00286     res["new_turn_expected_damage_inflicted"] = ss.str();
00287     ss.str(std::string());
00288     ss << new_turn_expected_damage_taken;
00289     res["new_turn_expected_damage_taken"] = ss.str();
00290 
00291     return res;
00292 }
00293 
00294 void stats::write(config_writer &out) const
00295 {
00296     out.open_child("recruits");
00297     write_str_int_map(out, recruits);
00298     out.close_child("recruits");
00299     out.open_child("recalls");
00300     write_str_int_map(out, recalls);
00301     out.close_child("recalls");
00302     out.open_child("advances");
00303     write_str_int_map(out, advanced_to);
00304     out.close_child("advances");
00305     out.open_child("deaths");
00306     write_str_int_map(out, deaths);
00307     out.close_child("deaths");
00308     out.open_child("killed");
00309     write_str_int_map(out, killed);
00310     out.close_child("killed");
00311     out.open_child("attacks");
00312     write_battle_result_map(out, attacks);
00313     out.close_child("attacks");
00314     out.open_child("defends");
00315     write_battle_result_map(out, defends);
00316     out.close_child("defends");
00317 
00318     std::stringstream ss;   
00319     ss << recruit_cost;
00320     out.write_key_val("recruit_cost", ss.str());
00321     ss.str(std::string());
00322     ss << recall_cost;
00323     out.write_key_val("recall_cost", ss.str());
00324 
00325     ss.str(std::string());
00326     ss << damage_inflicted;
00327     out.write_key_val("damage_inflicted", ss.str());
00328     ss.str(std::string());
00329     ss << damage_taken;
00330     out.write_key_val("damage_taken", ss.str());
00331     ss.str(std::string());
00332     ss << expected_damage_inflicted;
00333     out.write_key_val("expected_damage_inflicted", ss.str());
00334     ss.str(std::string());
00335     ss << expected_damage_taken;
00336     out.write_key_val("expected_damage_taken", ss.str());
00337     ss.str(std::string());
00338     ss << turn_damage_inflicted;
00339 
00340     out.write_key_val("turn_damage_inflicted", ss.str());
00341     ss.str(std::string());
00342     ss << turn_damage_taken;
00343     out.write_key_val("turn_damage_taken", ss.str());
00344     ss.str(std::string());
00345     ss << turn_expected_damage_inflicted;
00346     out.write_key_val("turn_expected_damage_inflicted", ss.str());
00347     ss.str(std::string());
00348     ss << turn_expected_damage_taken;
00349     out.write_key_val("turn_expected_damage_taken", ss.str());
00350 
00351     ss.str(std::string());
00352     ss << new_expected_damage_inflicted;
00353     out.write_key_val("new_expected_damage_inflicted", ss.str());
00354     ss.str(std::string());
00355     ss << new_expected_damage_taken;
00356     out.write_key_val("new_expected_damage_taken", ss.str());
00357     ss.str(std::string());
00358     ss << new_turn_expected_damage_inflicted;
00359     out.write_key_val("new_turn_expected_damage_inflicted", ss.str());
00360     ss.str(std::string());
00361     ss << new_turn_expected_damage_taken;
00362     out.write_key_val("new_turn_expected_damage_taken", ss.str());
00363 
00364 }
00365 
00366 void stats::read(const config& cfg)
00367 {
00368     if(cfg.child("recruits")) {
00369         recruits = read_str_int_map(*cfg.child("recruits"));
00370     }
00371     if(cfg.child("recalls")) {
00372         recalls = read_str_int_map(*cfg.child("recalls"));
00373     }
00374     if(cfg.child("advances")) {
00375         advanced_to = read_str_int_map(*cfg.child("advances"));
00376     }
00377     if(cfg.child("deaths")) {
00378         deaths = read_str_int_map(*cfg.child("deaths"));
00379     }
00380     if(cfg.child("killed")) {
00381         killed = read_str_int_map(*cfg.child("killed"));
00382     }
00383     if(cfg.child("recalls")) {
00384         recalls = read_str_int_map(*cfg.child("recalls"));
00385     }
00386     if(cfg.child("attacks")) {
00387         attacks = read_battle_result_map(*cfg.child("attacks"));
00388     }
00389     if(cfg.child("defends")) {
00390         defends = read_battle_result_map(*cfg.child("defends"));
00391     }
00392 
00393     recruit_cost = lexical_cast<long long>(cfg["recruit_cost"]);
00394     recall_cost = lexical_cast<long long>(cfg["recall_cost"]);
00395 
00396     damage_inflicted = lexical_cast<long long>(cfg["damage_inflicted"]);
00397     damage_taken = lexical_cast<long long>(cfg["damage_taken"]);
00398     expected_damage_inflicted = lexical_cast<long long>(cfg["expected_damage_inflicted"]);
00399     expected_damage_taken = lexical_cast<long long>(cfg["expected_damage_taken"]);
00400 
00401     turn_damage_inflicted = lexical_cast<long long>(cfg["turn_damage_inflicted"]);
00402     turn_damage_taken = lexical_cast<long long>(cfg["turn_damage_taken"]);
00403     turn_expected_damage_inflicted = lexical_cast<long long>(cfg["turn_expected_damage_inflicted"]);
00404     turn_expected_damage_taken = lexical_cast<long long>(cfg["turn_expected_damage_taken"]);
00405     
00406     new_expected_damage_inflicted = lexical_cast_default<long long>(cfg["new_expected_damage_inflicted"],expected_damage_inflicted);
00407     new_expected_damage_taken = lexical_cast_default<long long>(cfg["new_expected_damage_taken"],expected_damage_taken);
00408     new_turn_expected_damage_inflicted = lexical_cast_default<long long>(cfg["new_turn_expected_damage_inflicted"],turn_expected_damage_inflicted);
00409     new_turn_expected_damage_taken = lexical_cast_default<long long>(cfg["new_turn_expected_damage_taken"],turn_expected_damage_taken);
00410 }
00411 
00412 disabler::disabler() { stats_disabled++; }
00413 disabler::~disabler() { stats_disabled--; }
00414 
00415 scenario_context::scenario_context(const std::string& name)
00416 {
00417     if(!mid_scenario || master_stats.empty()) {
00418         master_stats.push_back(scenario_stats(name));
00419     }
00420 
00421     mid_scenario = true;
00422 }
00423 
00424 scenario_context::~scenario_context()
00425 {
00426     mid_scenario = false;
00427 }
00428 
00429 attack_context::attack_context(const unit& a, const unit& d, int a_cth, int d_cth)
00430    : attacker_type(a.type_id()), defender_type(d.type_id()),
00431      attacker_side(a.side()), defender_side(d.side()),
00432      chance_to_hit_defender(a_cth), chance_to_hit_attacker(d_cth)
00433 {
00434 }
00435 
00436 attack_context::~attack_context()
00437 {
00438     if(stats_disabled > 0)
00439         return;
00440 
00441     std::string attacker_key = "s" + attacker_res;
00442     std::string defender_key = "s" + defender_res;
00443 
00444     attacker_stats().attacks[chance_to_hit_defender][attacker_key]++;
00445     defender_stats().defends[chance_to_hit_attacker][defender_key]++;
00446 }
00447 
00448 stats& attack_context::attacker_stats()
00449 {
00450     return get_stats(attacker_side);
00451 }
00452 
00453 stats& attack_context::defender_stats()
00454 {
00455     return get_stats(defender_side);
00456 }
00457 
00458 void attack_context::attack_excepted_damage(double attacker_inflict_, double defender_inflict_)
00459 {
00460     const long long attacker_inflict = static_cast<long long>(attacker_inflict_ * stats::desimal_shift);
00461     const long long defender_inflict = static_cast<long long>(defender_inflict_ * stats::desimal_shift);
00462     attacker_stats().new_expected_damage_inflicted  += attacker_inflict;
00463     attacker_stats().new_expected_damage_taken  += defender_inflict;
00464     defender_stats().new_expected_damage_inflicted  += defender_inflict;
00465     defender_stats().new_expected_damage_taken  += attacker_inflict;
00466     attacker_stats().new_turn_expected_damage_inflicted += attacker_inflict;
00467     attacker_stats().new_turn_expected_damage_taken     += defender_inflict;
00468     defender_stats().new_turn_expected_damage_inflicted += defender_inflict;
00469     defender_stats().new_turn_expected_damage_taken     += attacker_inflict;
00470 }
00471 
00472 
00473 void attack_context::attack_result(attack_context::ATTACK_RESULT res, long long damage, long long drain)
00474 {
00475     if(stats_disabled > 0)
00476         return;
00477 
00478     push_back(attacker_res,(res == MISSES ? '0' : '1'));
00479 
00480     if(res != MISSES) {
00481         // handle drain
00482         attacker_stats().damage_taken -= drain;
00483         defender_stats().damage_inflicted -= drain;
00484         attacker_stats().turn_damage_taken -= drain;
00485         defender_stats().turn_damage_inflicted -= drain;
00486         
00487         attacker_stats().damage_inflicted += damage;
00488         defender_stats().damage_taken += damage;
00489         attacker_stats().turn_damage_inflicted += damage;
00490         defender_stats().turn_damage_taken += damage;
00491     }
00492     const int exp_damage = damage * chance_to_hit_defender * 10;
00493     const int exp_drain  = drain  * chance_to_hit_defender * 10;
00494 
00495     attacker_stats().expected_damage_taken -= exp_drain;
00496     defender_stats().expected_damage_inflicted -= exp_drain;
00497     attacker_stats().turn_expected_damage_taken -= exp_drain;
00498     defender_stats().turn_expected_damage_inflicted -= exp_drain;
00499 
00500     // handle drain
00501     attacker_stats().expected_damage_inflicted += exp_damage;
00502     defender_stats().expected_damage_taken += exp_damage;
00503     attacker_stats().turn_expected_damage_inflicted += exp_damage;
00504     defender_stats().turn_expected_damage_taken += exp_damage;
00505 
00506     if(res == KILLS) {
00507         attacker_stats().killed[defender_type]++;
00508         defender_stats().deaths[defender_type]++;
00509     }
00510 }
00511 
00512 void attack_context::defend_result(attack_context::ATTACK_RESULT res, long long damage, long long drain)
00513 {
00514     if(stats_disabled > 0)
00515         return;
00516 
00517     push_back(defender_res,(res == MISSES ? '0' : '1'));
00518 
00519 
00520     if(res != MISSES) {
00521         //handle drain
00522         defender_stats().damage_taken -= drain;
00523         attacker_stats().damage_inflicted -= drain;
00524         defender_stats().turn_damage_taken -= drain;
00525         attacker_stats().turn_damage_inflicted -= drain;
00526         
00527         attacker_stats().damage_taken += damage;
00528         defender_stats().damage_inflicted += damage;
00529         attacker_stats().turn_damage_taken += damage;
00530         defender_stats().turn_damage_inflicted += damage;
00531     }
00532     const long long exp_damage = damage * chance_to_hit_attacker * 10;
00533     const long long exp_drain = drain * chance_to_hit_attacker * 10;
00534     //handle drain
00535     defender_stats().expected_damage_taken -= exp_drain;
00536     attacker_stats().expected_damage_inflicted -= exp_drain;    
00537     defender_stats().turn_expected_damage_taken -= exp_drain;
00538     attacker_stats().turn_expected_damage_inflicted -= exp_drain;
00539     
00540     attacker_stats().expected_damage_taken += exp_damage;
00541     defender_stats().expected_damage_inflicted += exp_damage;
00542     attacker_stats().turn_expected_damage_taken += exp_damage;
00543     defender_stats().turn_expected_damage_inflicted += exp_damage;
00544 
00545     if(res == KILLS) {
00546         attacker_stats().deaths[attacker_type]++;
00547         defender_stats().killed[attacker_type]++;
00548     }
00549 }
00550 
00551 void recruit_unit(const unit& u)
00552 {
00553     if(stats_disabled > 0)
00554         return;
00555 
00556     stats& s = get_stats(u.side());
00557     s.recruits[u.type_id()]++;
00558     s.recruit_cost += u.cost();
00559 }
00560 
00561 void recall_unit(const unit& u)
00562 {
00563     if(stats_disabled > 0)
00564         return;
00565 
00566     stats& s = get_stats(u.side());
00567     s.recalls[u.type_id()]++;
00568     s.recall_cost += u.cost();
00569 }
00570 
00571 void un_recall_unit(const unit& u)
00572 {
00573     if(stats_disabled > 0)
00574         return;
00575 
00576     stats& s = get_stats(u.side());
00577     s.recalls[u.type_id()]--;
00578     s.recall_cost -= u.cost();
00579 }
00580 
00581 void un_recruit_unit(const unit& u)
00582 {
00583     if(stats_disabled > 0)
00584         return;
00585 
00586     stats& s = get_stats(u.side());
00587     s.recruits[u.type_id()]--;
00588     s.recruit_cost -= u.cost();
00589 }
00590 
00591 
00592 void advance_unit(const unit& u)
00593 {
00594     if(stats_disabled > 0)
00595         return;
00596 
00597     stats& s = get_stats(u.side());
00598     s.advanced_to[u.type_id()]++;
00599 }
00600 
00601 void reset_turn_stats(int side)
00602 {
00603     stats &s = get_stats(side);
00604     s.turn_damage_inflicted = 0;
00605     s.turn_damage_taken = 0;
00606     s.turn_expected_damage_inflicted = 0;
00607     s.turn_expected_damage_taken = 0;
00608     s.new_turn_expected_damage_inflicted = 0;
00609     s.new_turn_expected_damage_taken = 0;
00610 }
00611 
00612 stats calculate_stats(int category, int side)
00613 {
00614     if(category == 0) {
00615         stats res;
00616         for(int i = 1; i <= int(master_stats.size()); ++i) {
00617             merge_stats(res,calculate_stats(i,side));
00618         }
00619 
00620         return res;
00621     } else {
00622         const size_t index = master_stats.size() - size_t(category);
00623         const size_t side_index = size_t(side) - 1;
00624         if(index < master_stats.size() && side_index < master_stats[index].team_stats.size()) {
00625             return master_stats[index].team_stats[side_index];
00626         } else {
00627             return stats();
00628         }
00629     }
00630 }
00631 
00632 config write_stats()
00633 {
00634     config res;
00635     res["mid_scenario"] = (mid_scenario ? "true" : "false");
00636 
00637     for(std::vector<scenario_stats>::const_iterator i = master_stats.begin(); i != master_stats.end(); ++i) {
00638         res.add_child("scenario",i->write());
00639     }
00640 
00641     return res;
00642 }
00643 
00644 void write_stats(config_writer &out)
00645 {
00646     out.write_key_val("mid_scenario", mid_scenario ? "true" : "false");
00647 
00648     for(std::vector<scenario_stats>::const_iterator i = master_stats.begin(); i != master_stats.end(); ++i) {
00649         out.open_child("scenario");
00650         i->write(out);
00651         out.close_child("scenario");
00652     }
00653 }
00654 
00655 void read_stats(const config& cfg)
00656 {
00657     fresh_stats();
00658     mid_scenario = (utils::string_bool(cfg["mid_scenario"]));
00659 
00660     const config::child_list& scenarios = cfg.get_children("scenario");
00661     for(config::child_list::const_iterator i = scenarios.begin(); i != scenarios.end(); ++i) {
00662         master_stats.push_back(scenario_stats(**i));
00663     }
00664 }
00665 
00666 void fresh_stats()
00667 {
00668     master_stats.clear();
00669     mid_scenario = false;
00670 }
00671 
00672 void clear_current_scenario()
00673 {
00674     if(master_stats.empty() == false) {
00675         master_stats.pop_back();
00676         mid_scenario = false;
00677     }
00678 }
00679 
00680 int sum_str_int_map(const stats::str_int_map& m)
00681 {
00682     int res = 0;
00683     for(stats::str_int_map::const_iterator i = m.begin(); i != m.end(); ++i) {
00684         res += i->second;
00685     }
00686 
00687     return res;
00688 }
00689 
00690 } // end namespace statistics
00691 

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs