From 9824b17b31684d970e7beb1fb5eb619ed35a57e1 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sun, 26 Mar 2023 12:24:12 +0300 Subject: [PATCH 31/31] AI: Make kill_desire() return value adv_want That's what callers are expecting, and it both - Adds sub-integer accuracy with low values - Avoids overflows with high values Overflows reported by mortmann Debugging and testing by alain_bkr See osdn #46286 Signed-off-by: Marko Lindqvist --- ai/default/aidiplomat.c | 2 +- ai/default/aiunit.c | 27 ++++++++++++++------------- ai/default/aiunit.h | 11 +++++++---- ai/default/daimilitary.c | 3 ++- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ai/default/aidiplomat.c b/ai/default/aidiplomat.c index de491fc147..3c5fa9ad7f 100644 --- a/ai/default/aidiplomat.c +++ b/ai/default/aidiplomat.c @@ -263,7 +263,7 @@ void dai_choose_diplomat_offensive(struct ai_type *ait, /* Discourage long treks */ time_to_dest *= ((time_to_dest + 1) / 2); - /* Almost kill_desire */ + /* Almost kill_desire() */ want = (p_success * gain - p_failure * loss) / 100 - SHIELD_WEIGHTING * time_to_dest; if (want <= 0) { diff --git a/ai/default/aiunit.c b/ai/default/aiunit.c index 5571cd31b4..b54f33903f 100644 --- a/ai/default/aiunit.c +++ b/ai/default/aiunit.c @@ -320,36 +320,37 @@ int unittype_def_rating_squared(const struct unit_type *att_type, victims on same tile (we take values from best defender) - however I believe it's accurate just enough now and lost speed isn't worth that. --pasky - Benefit is something like 'attractiveness' of the victim, how nice it would be - to destroy it. Larger value, worse loss for enemy. + Benefit is something like 'attractiveness' of the victim, how nice it + would be to destroy it. Larger value, worse loss for enemy. - Attack is the total possible attack power we can throw on the victim. Note that - it usually comes squared. + Attack is the total possible attack power we can throw on the victim. + Note that it usually comes squared. - Loss is the possible loss when we would lose the unit we are attacking with (in - SHIELDs). + Loss is the possible loss when we would lose the unit we are attacking with + (in SHIELDs). Vuln is vulnerability of our unit when attacking the enemy. Note that it usually comes squared as well. Victim count is number of victims stacked in the target tile. Note that we - shouldn't treat cities as a stack (despite the code using this function) - the - scaling is probably different. (extremely dodgy usage of it -- GB) + shouldn't treat cities as a stack (despite the code using this function) - + the scaling is probably different. (extremely dodgy usage of it -- GB) **************************************************************************/ -int kill_desire(int benefit, int attack, int loss, int vuln, int victim_count) +adv_want kill_desire(int benefit, int attack, int loss, int vuln, + int victim_count) { - int desire; + adv_want desire; /* attractiveness danger */ - desire = (unsigned int) (benefit * attack - loss * vuln) * victim_count * - SHIELD_WEIGHTING / (attack + vuln * victim_count); + desire = (benefit * attack - loss * vuln) * victim_count + * SHIELD_WEIGHTING / (attack + vuln * victim_count); return desire; } /**********************************************************************//** Compute how much we want to kill certain victim we've chosen, counted in - SHIELDs. See comment to kill_desire. + SHIELDs. See comment to kill_desire(). chance -- the probability the action will succeed, benefit -- the benefit (in shields) that we are getting in the case of diff --git a/ai/default/aiunit.h b/ai/default/aiunit.h index 502381e0ad..eedbc626f9 100644 --- a/ai/default/aiunit.h +++ b/ai/default/aiunit.h @@ -109,7 +109,8 @@ bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile **ferry_dest, struct tile **beachhead_tile); adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer, struct unit *punit, - struct tile **pdest_tile, struct pf_path **ppath, + struct tile **pdest_tile, + struct pf_path **ppath, struct pf_map **pferrymap, struct unit **pferryboat, const struct unit_type **pboattype, @@ -119,8 +120,10 @@ int build_cost_balanced(const struct unit_type *punittype); int unittype_def_rating_squared(const struct unit_type *att_type, const struct unit_type *def_type, struct player *def_player, - struct tile *ptile, bool fortified, int veteran); -int kill_desire(int benefit, int attack, int loss, int vuln, int attack_count); + struct tile *ptile, bool fortified, + int veteran); +adv_want kill_desire(int benefit, int attack, int loss, int vuln, + int attack_count); const struct impr_type *utype_needs_improvement(const struct unit_type *putype, const struct city *pcity); @@ -165,4 +168,4 @@ bool dai_unit_can_strike_my_unit(const struct unit *attacker, void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow); -#endif /* FC__AIUNIT_H */ +#endif /* FC__AIUNIT_H */ diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index 82a59a7787..5650b3e112 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -1112,7 +1112,8 @@ bool dai_process_defender_want(struct ai_type *ait, struct player *pplayer, /* Yes, there's some similarity with kill_desire(). */ /* TODO: Explain what shield cost has to do with tech want. */ tech_desire[utype_index(punittype)] = - (desire * total_want / (utype_build_shield_cost(pcity, NULL, punittype) + tech_cost)); + (desire * total_want + / (utype_build_shield_cost(pcity, NULL, punittype) + tech_cost)); } } } simple_ai_unit_type_iterate_end; -- 2.39.2