From 706f696748488855ceebc7a14459ee9f57e03fd2 Mon Sep 17 00:00:00 2001 From: Ihnatus Date: Sat, 8 Apr 2023 21:16:25 +0300 Subject: [PATCH] Add utility function get_effect_expected_value() See osdn #47671 Signed-off-by: Ihnatus --- common/effects.c | 36 ++++++++++++++++++++++++++++++++++++ common/effects.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/common/effects.c b/common/effects.c index 647975db0c..b67df2e60a 100644 --- a/common/effects.c +++ b/common/effects.c @@ -709,6 +709,42 @@ int get_target_bonus_effects(struct effect_list *plist, return bonus; } +/**********************************************************************//** + Returns the expected value of the effect of given type for given context, + calculating value weighted with probability for each individual effect + with given callback using arbitrary additional data passed to it. + + The way of using multipliers is left on the callback. +**************************************************************************/ +double get_effect_expected_value(const struct player *target_player, + const struct player *other_player, + const struct city *target_city, + const struct impr_type *target_building, + const struct tile *target_tile, + const struct unit *target_unit, + const struct unit_type *target_unittype, + const struct output_type *target_output, + const struct specialist *target_specialist, + const struct action *target_action, + enum effect_type effect_type, + eft_value_filter_cb weighter, + void *data, int n_data) +{ + double sum = 0.; + + fc_assert_ret_val(weighter, 0.); + + /* Loop over all effects of this type. */ + effect_list_iterate(get_effects(effect_type), peffect) { + sum += weighter(peffect, target_player, other_player, target_city, + target_building, target_tile, target_unit, + target_unittype, target_output, target_specialist, + target_action, data, n_data); + } effect_list_iterate_end; + + return sum; +} + /************************************************************************** Returns the effect bonus for the whole world. **************************************************************************/ diff --git a/common/effects.h b/common/effects.h index 5c20e244fc..05a7e4e2d0 100644 --- a/common/effects.h +++ b/common/effects.h @@ -324,6 +324,23 @@ struct effect { struct requirement_vector reqs; }; +/* A callback type that takes an individual effect and a context for it + * and tells its weighted (by probability or something) value. + */ +typedef double + (*eft_value_filter_cb)(const struct effect *eft, + const struct player *target_player, + const struct player *other_player, + const struct city *target_city, + const struct impr_type *target_building, + const struct tile *target_tile, + const struct unit *target_unit, + const struct unit_type *target_unittype, + const struct output_type *target_output, + const struct specialist *target_specialist, + const struct action *target_action, + void *data, int n_data); + /* An effect_list is a list of effects. */ #define SPECLIST_TAG effect #define SPECLIST_TYPE struct effect @@ -422,6 +439,19 @@ int get_target_bonus_effects(struct effect_list *plist, const struct specialist *target_specialist, const struct action *target_action, enum effect_type effect_type); +double get_effect_expected_value(const struct player *target_player, + const struct player *other_player, + const struct city *target_city, + const struct impr_type *target_building, + const struct tile *target_tile, + const struct unit *target_unit, + const struct unit_type *target_unittype, + const struct output_type *target_output, + const struct specialist *target_specialist, + const struct action *target_action, + enum effect_type effect_type, + eft_value_filter_cb weighter, + void *data, int n_data); bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type); -- 2.37.2