From 1818074018347776954a7d0e689af84d9a92cfaa Mon Sep 17 00:00:00 2001 From: Ihnatus Date: Thu, 23 Mar 2023 22:05:31 +0300 Subject: [PATCH] A generic simple function to calculate effect expected value See #47671 Signed-off-by: Ihnatus --- common/effects.c | 28 ++++++++++++++++++++++++++++ common/effects.h | 14 ++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/common/effects.c b/common/effects.c index 6dc58b0a15..1e94e20434 100644 --- a/common/effects.c +++ b/common/effects.c @@ -1194,6 +1194,34 @@ void get_target_effects_limits(int *minv, int *maxv, } } +/**********************************************************************//** + 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 req_context *context, + const struct player *other_player, + enum effect_type effect_type, + eft_value_filter_cb weighter, + void *data, int n_data) +{ + double sum = 0.; + + fc_assert_ret_val(weighter, 0.); + if (context == NULL) { + context = req_context_empty(); + } + + /* Loop over all effects of this type. */ + effect_list_iterate(get_effects(effect_type), peffect) { + sum += weighter(peffect, context, other_player, 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 dad701a9e3..763eeb399d 100644 --- a/common/effects.h +++ b/common/effects.h @@ -381,6 +381,15 @@ struct effect { } rulesave; }; +/* 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 req_context *context, + const struct player *other_player, + void *data, int n_data); + /* An effect_list is a list of effects. */ #define SPECLIST_TAG effect #define SPECLIST_TYPE struct effect @@ -487,6 +496,11 @@ void get_target_effects_limits(int *minv, int *maxv, enum effect_type effect_type, req_tester_cb tester, void *data, int n_data); +double get_effect_expected_value(const struct req_context *context, + const struct player *other_player, + 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