From 6d707f27e15ad8d07aa43ee265daaad5e9a59f7b Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 8 Oct 2022 04:40:16 +0300 Subject: [PATCH 32/32] AI: Make military_amortize() to handle want as adv_want Made type changes recursively to callers too See osdn #45700 Signed-off-by: Marko Lindqvist --- ai/default/aiair.c | 39 ++++++++++++++++++++------------------- ai/default/aidiplomat.c | 8 +++++--- ai/default/aiferry.c | 1 + ai/default/aitech.c | 1 + ai/default/aitools.c | 12 ++++++------ ai/default/aitools.h | 23 ++++++++++------------- ai/default/aiunit.c | 33 +++++++++++++++++---------------- ai/default/aiunit.h | 15 ++++++++------- ai/default/daimilitary.c | 4 +++- ai/default/daimilitary.h | 4 +++- 10 files changed, 74 insertions(+), 66 deletions(-) diff --git a/ai/default/aiair.c b/ai/default/aiair.c index 91e3336905..cdc57541d0 100644 --- a/ai/default/aiair.c +++ b/ai/default/aiair.c @@ -161,8 +161,8 @@ static bool dai_should_we_air_attack_tile(struct ai_type *ait, Returns an estimate for the profit gained through attack. Assumes that the victim is within one day's flight **********************************************************************/ -static int dai_evaluate_tile_for_air_attack(struct unit *punit, - struct tile *dst_tile) +static adv_want dai_evaluate_tile_for_air_attack(struct unit *punit, + struct tile *dst_tile) { struct unit *pdefender; /* unit costs in shields */ @@ -170,7 +170,7 @@ static int dai_evaluate_tile_for_air_attack(struct unit *punit, /* unit stats */ int unit_attack, victim_defence; /* final answer */ - int profit; + adv_want profit; /* time spent in the air */ int sortie_time; #define PROB_MULTIPLIER 100 /* should unify with those in combat.c */ @@ -221,10 +221,10 @@ static int dai_evaluate_tile_for_air_attack(struct unit *punit, profit = military_amortize(unit_owner(punit), game_city_by_number(punit->homecity), profit, sortie_time, balanced_cost); - log_debug("%s at (%d, %d) is a worthy target with profit %d", + log_debug("%s at (%d, %d) is a worthy target with profit " ADV_WANT_PRINTF, unit_rule_name(pdefender), TILE_XY(dst_tile), profit); } else { - log_debug("%s(%d, %d): %s at (%d, %d) is unworthy with profit %d", + log_debug("%s(%d, %d): %s at (%d, %d) is unworthy with profit " ADV_WANT_PRINTF, unit_rule_name(punit), TILE_XY(unit_tile(punit)), unit_rule_name(pdefender), TILE_XY(dst_tile), profit); profit = 0; @@ -232,7 +232,6 @@ static int dai_evaluate_tile_for_air_attack(struct unit *punit, return profit; } - /******************************************************************//** Find something to bomb @@ -243,14 +242,14 @@ static int dai_evaluate_tile_for_air_attack(struct unit *punit, TODO: make separate handicaps for air units seeing targets IMO should be more restrictive than general H_MAP, H_FOG **********************************************************************/ -static int find_something_to_bomb(struct ai_type *ait, struct unit *punit, - struct pf_path **path, struct tile **pptile) +static adv_want find_something_to_bomb(struct ai_type *ait, struct unit *punit, + struct pf_path **path, struct tile **pptile) { struct player *pplayer = unit_owner(punit); struct pf_parameter parameter; struct pf_map *pfm; struct tile *best_tile = NULL; - int best = 0; + adv_want best = 0; pft_fill_unit_parameter(¶meter, punit); parameter.omniscience = !has_handicap(pplayer, H_MAP); @@ -277,12 +276,12 @@ static int find_something_to_bomb(struct ai_type *ait, struct unit *punit, if (is_enemy_unit_tile(ptile, pplayer) && dai_should_we_air_attack_tile(ait, punit, ptile) && can_unit_attack_tile(punit, NULL, ptile)) { - int new_best = dai_evaluate_tile_for_air_attack(punit, ptile); + adv_want new_best = dai_evaluate_tile_for_air_attack(punit, ptile); if (new_best > best) { best_tile = ptile; best = new_best; - log_debug("%s wants to attack tile (%d, %d)", + log_debug("%s wants to attack tile (%d, %d)", unit_rule_name(punit), TILE_XY(ptile)); } } @@ -297,8 +296,9 @@ static int find_something_to_bomb(struct ai_type *ait, struct unit *punit, } pf_map_destroy(pfm); + return best; -} +} /******************************************************************//** Iterates through reachable refuel points and appraises them @@ -321,7 +321,7 @@ static struct tile *dai_find_strategic_airbase(struct ai_type *ait, struct tile *best_tile = NULL; struct city *pcity; struct unit *pvirtual = NULL; - int best_worth = 0, target_worth; + adv_want best_worth = 0, target_worth; int lost_hp = unit_type_get(punit)->hp - punit->hp; int regen_turns_min = FC_INFINITY; bool defend = FALSE; /* Used only for lost_hp > 0 */ @@ -434,7 +434,8 @@ static struct tile *dai_find_strategic_airbase(struct ai_type *ait, unit_type_get(punit), punit->veteran); if (refuel_start) { /* What worth really worth moving out? */ - int start_worth; + adv_want start_worth; + unit_tile_set(pvirtual, unit_tile(punit)); start_worth = find_something_to_bomb(ait, pvirtual, NULL, NULL); best_worth = MAX(start_worth, 0); @@ -579,12 +580,12 @@ bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer, { bool want_something = FALSE; - /* This AI doesn't know to build planes */ + /* This AI doesn't know how to build planes */ if (has_handicap(pplayer, H_NOPLANES)) { return FALSE; } - /* military_advisor_choose_build does something idiotic, + /* military_advisor_choose_build() does something idiotic, * this function should not be called if there is danger... */ if (choice->want >= 100 && choice->type != CT_ATTACKER) { return FALSE; @@ -614,7 +615,7 @@ bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer, unit_virtual_create( pplayer, pcity, punittype, city_production_unit_veteran_level(pcity, punittype)); - int profit = find_something_to_bomb(ait, virtual_unit, NULL, NULL); + adv_want profit = find_something_to_bomb(ait, virtual_unit, NULL, NULL); if (profit > choice->want) { /* Update choice */ @@ -624,10 +625,10 @@ bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer, choice->need_boat = FALSE; adv_choice_set_use(choice, "offensive air"); want_something = TRUE; - log_debug("%s wants to build %s (want=%d)", + log_debug("%s wants to build %s (want = " ADV_WANT_PRINTF ")", city_name_get(pcity), utype_rule_name(punittype), profit); } else { - log_debug("%s doesn't want to build %s (want=%d)", + log_debug("%s doesn't want to build %s (want = " ADV_WANT_PRINTF ")", city_name_get(pcity), utype_rule_name(punittype), profit); } unit_virtual_destroy(virtual_unit); diff --git a/ai/default/aidiplomat.c b/ai/default/aidiplomat.c index 49f76a4831..93d6f1eabf 100644 --- a/ai/default/aidiplomat.c +++ b/ai/default/aidiplomat.c @@ -188,7 +188,8 @@ void dai_choose_diplomat_offensive(struct ai_type *ait, struct pf_map *pfm; struct pf_parameter parameter; struct city *acity; - int want, loss, p_success, p_failure, time_to_dest; + adv_want want; + int loss, p_success, p_failure, time_to_dest; int gain_incite = 0, gain_theft = 0, gain = 1; int incite_cost; struct unit *punit = unit_virtual_create( @@ -288,8 +289,9 @@ void dai_choose_diplomat_offensive(struct ai_type *ait, } if (want > choice->want) { log_base(LOG_DIPLOMAT_BUILD, - "%s, %s: %s is desired with want %d to spy in %s (incite " - "want %d cost %d gold %d, tech theft want %d, ttd %d)", + "%s, %s: %s is desired with want " ADV_WANT_PRINTF + " to spy in %s (incite want %d cost %d gold %d, " + "tech theft want %d, ttd %d)", player_name(pplayer), city_name_get(pcity), utype_rule_name(ut), diff --git a/ai/default/aiferry.c b/ai/default/aiferry.c index 02a7ff1e7e..a71601abea 100644 --- a/ai/default/aiferry.c +++ b/ai/default/aiferry.c @@ -52,6 +52,7 @@ #include "aiplayer.h" #include "aitools.h" #include "aiunit.h" +#include "daicity.h" #include "aiferry.h" diff --git a/ai/default/aitech.c b/ai/default/aitech.c index 5f1c7dd527..30da5d38b7 100644 --- a/ai/default/aitech.c +++ b/ai/default/aitech.c @@ -40,6 +40,7 @@ #include "ailog.h" #include "aiplayer.h" #include "aitools.h" +#include "daicity.h" #include "daieffects.h" #include "aitech.h" diff --git a/ai/default/aitools.c b/ai/default/aitools.c index f637d417b7..c656be0438 100644 --- a/ai/default/aitools.c +++ b/ai/default/aitools.c @@ -130,14 +130,14 @@ const char *dai_choice_rule_name(const struct adv_choice *choice) /**********************************************************************//** Amortize a want modified by the shields (build_cost) we risk losing. - We add the build time of the unit(s) we risk to amortize delay. The + We add the build time of the unit(s) we risk to amortize delay. The build time is calculated as the build cost divided by the production output of the unit's homecity or the city where we want to produce the unit. If the city has less than average shield output, we instead use the average, to encourage long-term thinking. **************************************************************************/ -int military_amortize(struct player *pplayer, struct city *pcity, - int value, int delay, int build_cost) +adv_want military_amortize(struct player *pplayer, struct city *pcity, + adv_want value, int delay, int build_cost) { struct adv_data *ai = adv_data_get(pplayer, NULL); int city_output = (pcity ? pcity->surplus[O_SHIELD] : 1); @@ -1326,11 +1326,11 @@ int dai_gold_reserve(struct player *pplayer) } /**********************************************************************//** - Adjust want for choice to 'value' percent + Adjust want for choice to given percentage. **************************************************************************/ -void adjust_choice(int value, struct adv_choice *choice) +void adjust_choice(int pct, struct adv_choice *choice) { - choice->want = (choice->want *value)/100; + choice->want = (choice->want * pct) / 100; } /**********************************************************************//** diff --git a/ai/default/aitools.h b/ai/default/aitools.h index e343965bb5..d60d7d0d02 100644 --- a/ai/default/aitools.h +++ b/ai/default/aitools.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 @@ -16,26 +16,23 @@ /* utility */ #include "support.h" /* bool type */ -/* common */ -#include "fc_types.h" -#include "unit.h" /* enum ai_unit_task */ - /* server/advisors */ -#include "advgoto.h" +#include "advchoice.h" /* ai/default */ -#include "aiunit.h" -#include "daicity.h" +#include "aiunit.h" /* enum ai_unit_task */ struct pf_path; struct pf_parameter; struct pft_amphibious; +struct adv_risk_cost; + const char *dai_unit_task_rule_name(const enum ai_unit_task task); const char *dai_choice_rule_name(const struct adv_choice *choice); -int military_amortize(struct player *pplayer, struct city *pcity, - int value, int delay, int build_cost); +adv_want military_amortize(struct player *pplayer, struct city *pcity, + adv_want value, int delay, int build_cost); int stack_cost(struct unit *pattacker, struct unit *pdefender); void dai_unit_move_or_attack(struct ai_type *ait, struct unit *punit, @@ -48,7 +45,7 @@ void dai_fill_unit_param(struct ai_type *ait, bool dai_gothere(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dst_tile); struct tile *immediate_destination(struct unit *punit, - struct tile *dest_tile); + struct tile *dest_tile); void dai_log_path(struct unit *punit, struct pf_path *path, struct pf_parameter *parameter); bool dai_unit_goto_constrained(struct ai_type *ait, struct unit *punit, @@ -69,7 +66,7 @@ bool dai_unit_move(struct ai_type *ait, struct unit *punit, struct tile *ptile); void dai_government_change(struct player *pplayer, struct government *gov); int dai_gold_reserve(struct player *pplayer); -void adjust_choice(int value, struct adv_choice *choice); +void adjust_choice(int pct, struct adv_choice *choice); bool dai_choose_role_unit(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, @@ -83,4 +80,4 @@ void dai_consider_plr_dangerous(struct ai_type *ait, struct player *plr1, struct player *plr2, enum override_bool *result); -#endif /* FC__AITOOLS_H */ +#endif /* FC__AITOOLS_H */ diff --git a/ai/default/aiunit.c b/ai/default/aiunit.c index b5a40bdaa6..6eb87a79a5 100644 --- a/ai/default/aiunit.c +++ b/ai/default/aiunit.c @@ -1120,12 +1120,12 @@ bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, punit->id == 0 means that the unit is virtual (considered to be built). **************************************************************************/ -int find_something_to_kill(struct ai_type *ait, struct player *pplayer, - struct unit *punit, - struct tile **pdest_tile, struct pf_path **ppath, - struct pf_map **pferrymap, - struct unit **pferryboat, - const struct unit_type **pboattype, int *pmove_time) +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 pf_map **pferrymap, + struct unit **pferryboat, + const struct unit_type **pboattype, int *pmove_time) { const int attack_value = adv_unit_att_rating(punit); /* basic attack. */ struct pf_parameter parameter; @@ -1156,9 +1156,9 @@ int find_something_to_kill(struct ai_type *ait, struct player *pplayer, * p_a_w isn't called, and we end up not wanting ironclads and therefore * never learning steam engine, even though ironclads would be very * useful. -- Syela */ - int bk = 0; - int want; /* Want (amortized) of the operaton. */ - int best = 0; /* Best of all wants. */ + adv_want bk = 0; + adv_want want; /* Want (amortized) of the operaton. */ + adv_want best = 0; /* Best of all wants. */ struct tile *goto_dest_tile = NULL; bool can_occupy; @@ -1454,12 +1454,12 @@ int find_something_to_kill(struct ai_type *ait, struct player *pplayer, bcost_bal + needferry); /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE. */ - if (0 >= want && 0 == punit->id && 0 == best) { - int bk_e = military_amortize(pplayer, - game_city_by_number(punit->homecity), - benefit * SHIELD_WEIGHTING, - MAX(1, move_time), - bcost_bal + needferry); + if (0 >= want && 0 == punit->id && 0 >= best) { + adv_want bk_e = military_amortize(pplayer, + game_city_by_number(punit->homecity), + benefit * SHIELD_WEIGHTING, + MAX(1, move_time), + bcost_bal + needferry); if (bk_e > bk) { *pdest_tile = atile; @@ -1487,7 +1487,8 @@ int find_something_to_kill(struct ai_type *ait, struct player *pplayer, && punit_class->adv.sea_move == MOVE_NONE) { UNIT_LOG(LOG_DEBUG, punit, "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)" - " (go_by_boat=%d, move_time=%d, want=%d, best=%d)", + " (go_by_boat = %d, move_time = %d, want = " ADV_WANT_PRINTF + ", best = " ADV_WANT_PRINTF ")", __FUNCTION__, unit_rule_name(ferryboat), TILE_XY(unit_tile(ferryboat)), city_name_get(acity), TILE_XY(atile), go_by_boat, move_time, want, best); diff --git a/ai/default/aiunit.h b/ai/default/aiunit.h index bd04000fe5..502381e0ad 100644 --- a/ai/default/aiunit.h +++ b/ai/default/aiunit.h @@ -16,6 +16,7 @@ /* common */ #include "combat.h" #include "fc_types.h" +#include "terrain.h" #include "unittype.h" struct pf_map; @@ -106,13 +107,13 @@ bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile *dest_tile, const struct unit_type *cargo_type, struct tile **ferry_dest, struct tile **beachhead_tile); -int find_something_to_kill(struct ai_type *ait, struct player *pplayer, - struct unit *punit, - struct tile **pdest_tile, struct pf_path **ppath, - struct pf_map **pferrymap, - struct unit **pferryboat, - const struct unit_type **pboattype, - int *pmove_time); +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 pf_map **pferrymap, + struct unit **pferryboat, + const struct unit_type **pboattype, + int *pmove_time); int build_cost_balanced(const struct unit_type *punittype); int unittype_def_rating_squared(const struct unit_type *att_type, diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index 45768b859b..ec286e0878 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -43,6 +43,7 @@ #include "advbuilding.h" #include "advchoice.h" #include "advdata.h" +#include "advgoto.h" #include "advtools.h" #include "autosettlers.h" #include "infracache.h" /* adv_city */ @@ -1236,7 +1237,8 @@ static void process_attacker_want(struct ai_type *ait, If the target is overseas, the function might suggest building a ferry to carry a land attack unit, instead of the land attack unit itself. **************************************************************************/ -static struct adv_choice *kill_something_with(struct ai_type *ait, struct player *pplayer, +static struct adv_choice *kill_something_with(struct ai_type *ait, + struct player *pplayer, struct city *pcity, struct unit *myunit, struct adv_choice *choice) { diff --git a/ai/default/daimilitary.h b/ai/default/daimilitary.h index 40ccf6b104..6f7e04a20c 100644 --- a/ai/default/daimilitary.h +++ b/ai/default/daimilitary.h @@ -20,9 +20,11 @@ /* server/advisors */ #include "advchoice.h" +struct civ_map; + #ifdef FREECIV_WEB #define ASSESS_DANGER_MAX_DISTANCE 40 -#define AI_HANDICAP_DISTANCE_LIMIT 6 //TODO: 20 for non-web +#define AI_HANDICAP_DISTANCE_LIMIT 6 /* TODO: 20 for non-web */ #endif /* FREECIV_WEB */ /* When an enemy has this or lower number of cities left, try harder -- 2.35.1