15 #define GETTEXT_DOMAIN "wesnoth-lib"
40 std::ostringstream ss;
45 ss << std::fixed << std::setprecision(1) << 100.0 * prob;
58 , campaign_(statistics.calculate_stats(current_team.save_id_or_number()))
59 , scenarios_(statistics.level_stats(current_team.save_id_or_number()))
60 , selection_index_(scenarios_.
size())
70 label& title = find_widget<label>(&
window,
"title",
false);
76 std::vector<config> menu_items;
79 menu_items.emplace_back(
"label",
_(
"All Scenarios"));
82 menu_items.emplace_back(
"label", *scenario.first);
85 menu_button& scenario_menu = find_widget<menu_button>(&
window,
"scenario_menu",
false);
95 listbox& stat_list = find_widget<listbox>(&
window,
"stats_list_main",
false);
110 listbox& stat_list = find_widget<listbox>(
get_window(),
"stats_list_main",
false);
134 str <<
"+0% (0 + 0)";
136 str << (
formatter() << std::showpos << std::round((actual - expected) * 100 / expected) <<
"% (").str();
137 str << expected << (actual >= expected ?
" + " :
" − ")
138 <<
static_cast<unsigned int>(std::round(std::abs(expected - actual)));
145 const std::string&
type,
146 const long long& damage,
147 const long long& expected,
148 const long long& turn_damage,
149 const long long& turn_expected,
150 const bool show_this_turn)
152 listbox& damage_list = find_widget<listbox>(
get_window(),
"stats_list_damage",
false);
162 const auto damage_str = [](
long long damage,
long long expected) {
163 const long long shifted = ((expected * 20) + shift) / (2 * shift);
164 std::ostringstream str;
169 item[
"label"] = damage_str(damage, expected);
170 data.emplace(
"damage_overall",
item);
173 data.emplace(
"overall_score",
item);
176 label& this_turn_header = find_widget<label>(
get_window(),
"damage_this_turn_header",
false);
179 item[
"label"] = damage_str(turn_damage, turn_expected);
180 data.emplace(
"damage_this_turn",
item);
183 data.emplace(
"this_turn_score",
item);
186 label& this_turn_header = find_widget<label>(
get_window(),
"damage_this_turn_header",
false);
207 unsigned int overall_hits = 0;
208 double expected_hits = 0;
209 unsigned int overall_strikes = 0;
211 std::ostringstream str, str2,
tooltip;
213 tooltip <<
'\n' <<
'\n' <<
_(
"Actual hit rates, by chance to hit:");
215 tooltip <<
'\n' <<
_(
"(no attacks have taken place yet)");
216 for(
const auto&
i : by_cth) {
218 overall_hits +=
i.second.hits;
219 expected_hits += (cth * 0.01) *
i.second.strikes;
220 overall_strikes +=
i.second.strikes;
221 tooltip <<
"\n" << cth <<
"%: "
223 <<
"% (N=" <<
i.second.strikes <<
")";
231 "id",
"statistics_dialog_dummy_defender",
234 "hitpoints", overall_strikes
240 auto current_defender = std::make_unique<combatant>(defender_bc);
242 for(
const auto&
i : by_cth) {
245 "id",
"statistics_dialog_dummy_attacker" + std::to_string(cth),
253 auto attack = std::make_shared<attack_type>(
config(
256 "name",
"dummy attack",
258 "number",
i.second.strikes
265 current_defender.reset(
new combatant(*current_defender, defender_bc));
268 attacker.
fight(*current_defender);
271 const std::vector<double>& final_hp_dist = current_defender->hp_dist;
272 const auto chance_of_exactly_N_hits = [&final_hp_dist](
int n) {
return final_hp_dist[final_hp_dist.size() - 1 -
n]; };
276 double probability_lt = 0.0;
277 for(
unsigned int i = 0;
i < overall_hits; ++
i) {
278 probability_lt += chance_of_exactly_N_hits(
i);
281 double probability_eq = chance_of_exactly_N_hits(overall_hits);
283 double probability_gt = 1.0 - (probability_lt + probability_eq);
285 if(overall_strikes == 0) {
289 const auto add_probability = [&str2](
double probability,
bool more_is_better) {
297 const double percentile = (probability_lt + (1.0 - probability_gt)) / 2.0;
298 add_probability(percentile, more_is_better);
306 const std::string&
type,
307 const bool more_is_better,
310 const bool show_this_turn)
312 listbox& hits_list = find_widget<listbox>(
get_window(),
"stats_list_hits",
false);
322 const auto tooltip_static_part =
_(
323 "stats dialog^Difference of actual outcome to expected outcome, as a percentage.\n"
324 "The first number in parentheses is the expected number of hits inflicted/taken.\n"
325 "The sum (or difference) of the two numbers in parentheses is the actual number of hits inflicted/taken.");
326 element =
tally(by_cth, more_is_better);
327 item[
"tooltip"] = tooltip_static_part + element.
tooltip;
335 label& this_turn_header = find_widget<label>(
get_window(),
"hits_this_turn_header",
false);
338 element =
tally(turn_by_cth, more_is_better);
339 item[
"tooltip"] = tooltip_static_part + element.
tooltip;
341 data.emplace(
"hits_this_turn",
item);
347 label& this_turn_header = find_widget<label>(
get_window(),
"hits_this_turn_header",
false);
359 listbox& stat_list = find_widget<listbox>(
get_window(),
"stats_list_main",
false);
374 if(last_selected_stat_row != -1) {
386 listbox& damage_list = find_widget<listbox>(
get_window(),
"stats_list_damage",
false);
390 listbox& hits_list = find_widget<listbox>(
get_window(),
"stats_list_hits",
false);
422 const std::size_t new_index = find_widget<menu_button>(
get_window(),
"scenario_menu",
false).get_value();
432 const int selected_row = find_widget<listbox>(
get_window(),
"stats_list_main",
false).get_selected_row();
433 if(selected_row == -1) {
454 item[
"label"] =
VGETTEXT(
"$count|× $name", {{
"count", std::to_string(
i.second)}, {
"name",
type->type_name()}});
Various functions that implement attacks and attack calculations.
A config object defines a single node in a WML file, with access to child nodes.
unsigned add_row(const unsigned count=1)
Abstract base class for all modal dialogs.
window * get_window()
Returns a pointer to the dialog's window.
std::size_t selection_index_
const team & current_team_
const statistics_t::stats & current_stats()
Picks out the stats structure that was selected for displaying.
void on_primary_list_select()
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
const statistics_t::levels scenarios_
void on_scenario_select()
void add_damage_row(const std::string &type, const long long &damage, const long long &expected, const long long &turn_damage, const long long &turn_expected, const bool show_this_turn)
Add a row to the Damage table.
const statistics_t::stats campaign_
void add_hits_row(const std::string &type, const bool more_is_better, const statistics_t::stats::hitrate_map &by_cth, const statistics_t::stats::hitrate_map &turn_by_cth, const bool show_this_turn)
Add a row to the Hits table.
void add_stat_row(const std::string &type, const statistics_t::stats::str_int_map &value, const bool has_cost=true)
std::vector< const statistics_t::stats::str_int_map * > main_stat_table_
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
bool select_row(const unsigned row, const bool select=true)
Selects a row.
void clear()
Removes all the rows in the listbox, clearing it.
int get_selected_row() const
Returns the first selected row.
base class of top level items, the only item which needs to store the final canvases to draw on.
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
static int sum_cost_str_int_map(const std::map< std::string, int > &m)
static int sum_str_int_map(const std::map< std::string, int > &m)
This class stores all the data for a single 'side' (in game nomenclature).
const std::string & color() const
const std::string & side_name() const
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
void build_unit_type(const unit_type &ut, unit_type::BUILD_STATUS status) const
Makes sure the provided unit_type is built to the specified level.
A single unit type that the player may recruit.
static std::string _(const char *str)
std::string tooltip
Shown when hovering over an entry in the filter's drop-down list.
const std::string unicode_em_dash
std::string span_color(const color_t &color)
Returns a Pango formatting string using the provided color_t object.
color_t red_to_green(double val, bool for_text)
Return a color corresponding to the value val red for val=0.0 to green for val=100....
REGISTER_DIALOG(editor_edit_unit)
static std::ostream & write_actual_and_expected(std::ostream &str, const long long actual, const double expected)
static std::string get_probability_string(const double prob)
static hitrate_table_element tally(const statistics_t::stats::hitrate_map &by_cth, const bool more_is_better)
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
std::map< std::string, widget_item > widget_data
std::map< std::string, t_string > widget_item
std::pair< std::string, unsigned > item
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
static std::string get_probability_string(const double prob)
Structure describing the statistics of a unit involved in the battle.
void fight(combatant &opponent, bool levelup_considered=true)
Simulate a fight! Can be called multiple times for cumulative calculations.
long long turn_damage_taken
long long turn_expected_damage_taken
hitrate_map by_cth_inflicted
hitrate_map turn_by_cth_inflicted
std::map< int, hitrate_t > hitrate_map
A type that maps chance-to-hit percentage to number of hits and strikes at that CTH.
long long turn_damage_inflicted
std::map< std::string, int > str_int_map
static const int decimal_shift
long long turn_expected_damage_inflicted
hitrate_map turn_by_cth_taken
long long expected_damage_inflicted
long long expected_damage_taken
long long damage_inflicted
static map_location::DIRECTION n
unit_type_data unit_types