From cc96a0f620d6d36d4f9ac3370b1be1ba10d5bec4 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 22 Apr 2023 14:37:59 +0300 Subject: [PATCH 34/34] AI: Correct equality tests between float adv_want values See osdn #47901 Signed-off-by: Marko Lindqvist --- ai/default/daimilitary.c | 6 ++++-- common/fc_types.h | 2 ++ server/advisors/advtools.h | 8 +++++--- server/advisors/autosettlers.c | 3 ++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index 535aae97e5..76c9bcc2fa 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -113,7 +113,8 @@ struct unit_type *dai_choose_defender_versus(struct city *pcity, TILE_XY(attacker->tile), want); #endif /* NEVER */ - if (want > best || (want == best && cost <= best_cost)) { + if (want > best || (ADV_WANTS_EQ(want, best) + && cost <= best_cost)) { best = want; bestunit = punittype; best_cost = cost; @@ -800,7 +801,8 @@ bool dai_process_defender_want(struct ai_type *ait, struct player *pplayer, if ((best_unit_cost > limit_cost && build_cost < best_unit_cost) || ((desire > best || - (desire == best && build_cost <= best_unit_cost)) + (ADV_WANTS_EQ(desire, best) + && build_cost <= best_unit_cost)) && (best_unit_type == NULL /* In case all units are more expensive than limit_cost */ || limit_cost <= pcity->shield_stock + 40))) { diff --git a/common/fc_types.h b/common/fc_types.h index 91dc81d50f..f61e950174 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -969,6 +969,8 @@ enum spaceship_place_type { #define SPECENUM_VALUE2NAME "Nation" #include "specenum_gen.h" +#define FC_EPSILON (0.000001) + typedef float adv_want; #define ADV_WANT_PRINTF "%f" diff --git a/server/advisors/advtools.h b/server/advisors/advtools.h index 4cc5ebf7ef..b357fbbe64 100644 --- a/server/advisors/advtools.h +++ b/server/advisors/advtools.h @@ -1,4 +1,4 @@ -/********************************************************************** +/*********************************************************************** Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,8 @@ #define MORT 24 +#define ADV_WANTS_EQ(_w1, _w2) (fabs((_w1) - (_w2)) < FC_EPSILON) + adv_want amortize(adv_want benefit, int delay); /* @@ -25,6 +27,6 @@ adv_want amortize(adv_want benefit, int delay); * is divided by POWER_DIVIDER. * */ -#define POWER_DIVIDER (POWER_FACTOR * 3) +#define POWER_DIVIDER (POWER_FACTOR * 3) -#endif /* FC__ADVTOOLS_H */ +#endif /* FC__ADVTOOLS_H */ diff --git a/server/advisors/autosettlers.c b/server/advisors/autosettlers.c index 8edfd500c0..8df9aaf0d3 100644 --- a/server/advisors/autosettlers.c +++ b/server/advisors/autosettlers.c @@ -336,7 +336,8 @@ static void consider_settler_action(const struct player *pplayer, * Getting the best possible total for next citizen to work on is more * important than amount tile gets improved. */ if (improves && (new_tile_value > *best_value - || (new_tile_value == *best_value && old_tile_value < *best_old_tile_value))) { + || (ADV_WANTS_EQ(new_tile_value, *best_value) + && old_tile_value < *best_old_tile_value))) { *best_value = new_tile_value; *best_old_tile_value = old_tile_value; *best_extra = extra; -- 2.39.2