[Freeciv-Dev] (PR#12262) Fix AI wonder building
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: |
[Freeciv-Dev] (PR#12262) Fix AI wonder building |
From: |
"Per I. Mathisen" <per@xxxxxxxxxxx> |
Date: |
Tue, 15 Feb 2005 04:14:58 -0800 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12262 >
This patch:
- designates one city as a 'wonder city', depending on location and
production
- only this city will build wonders; it will try not build much else
- wonder city may change, but rarely
- mostly rewrites help_wonder caravan code, now faster and leaner
- adding modifier for losing shields; this means however that looking at
building want for cities that are already building something will no
longer be as easy, as you must keep this in mind
- simplified ai_advisor_choose_building()
After this patch goes in, we should start looking at wonder wants again,
to ensure the correct wonders are being built, now that fiddling with such
wants no longer runs the risk of setting the entire AI civ into wonder
mode.
- Per
Index: ai/advdomestic.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdomestic.c,v
retrieving revision 1.126
diff -u -r1.126 advdomestic.c
--- ai/advdomestic.c 3 Feb 2005 09:48:53 -0000 1.126
+++ ai/advdomestic.c 15 Feb 2005 12:07:30 -0000
@@ -48,11 +48,10 @@
* stimulated.
***************************************************************************/
static void ai_choose_help_wonder(struct city *pcity,
- struct ai_choice *choice)
+ struct ai_choice *choice,
+ struct ai_data *ai)
{
struct player *pplayer = city_owner(pcity);
- /* Continent where the city is --- we won't be aiding any wonder
- * construction on another continent */
Continent_id continent = map_get_continent(pcity->tile);
/* Total count of caravans available or already being built
* on this continent */
@@ -65,6 +64,16 @@
return;
}
+ if (pcity == ai->wonder_city
+ || ai->wonder_city == NULL
+ || pcity->ai.distance_to_wonder_city <= 0
+ || ai->wonder_city->is_building_unit
+ || !is_wonder(ai->wonder_city->currently_building)) {
+ /* A distance of zero indicates we are very far away, possibly
+ * on another continent. */
+ return;
+ }
+
/* Count existing caravans */
unit_list_iterate(pplayer->units, punit) {
if (unit_flag(punit, F_HELP_WONDER)
@@ -76,70 +85,44 @@
city_list_iterate(pplayer->cities, acity) {
if (acity->is_building_unit
&& unit_type_flag(acity->currently_building, F_HELP_WONDER)
- && (acity->shield_stock
- >= unit_build_shield_cost(acity->currently_building))
&& map_get_continent(acity->tile) == continent) {
caravans++;
}
} city_list_iterate_end;
- /* Check all wonders in our cities being built, if one isn't worth a little
- * help */
- city_list_iterate(pplayer->cities, acity) {
- unit_type = best_role_unit(pcity, F_HELP_WONDER);
-
- if (unit_type == U_LAST) {
- /* We cannot build such units yet
- * but we will consider it to stimulate science */
- unit_type = get_role_unit(F_HELP_WONDER, 0);
- }
-
- /* If we are building wonder there, the city is on same continent, we
- * aren't in that city (stopping building wonder in order to build caravan
- * to help it makes no sense) and we haven't already got enough caravans
- * to finish the wonder. */
- if (!acity->is_building_unit
- && is_wonder(acity->currently_building)
- && map_get_continent(acity->tile) == continent
- && acity != pcity
- && (build_points_left(acity)
- > unit_build_shield_cost(unit_type) * caravans)) {
-
- /* Desire for the wonder we are going to help - as much as we want to
- * build it we want to help building it as well. */
- int want = pcity->ai.building_want[acity->currently_building];
-
- /* Distance to wonder city was established after ai_manage_buildings()
- * and before this. If we just started building a wonder during
- * ai_city_choose_build(), the started_building notify comes equipped
- * with an update. It calls generate_warmap(), but this is a lot less
- * warmap generation than there would be otherwise. -- Syela *
- * Value of 8 is a total guess and could be wrong, but it's still better
- * than 0. -- Syela */
- int dist = pcity->ai.distance_to_wonder_city * 8 /
- get_unit_type(unit_type)->move_rate;
+ unit_type = best_role_unit(pcity, F_HELP_WONDER);
- want -= dist;
-
- if (can_build_unit_direct(pcity, unit_type)) {
- if (want > choice->want) {
- choice->want = want;
- choice->type = CT_NONMIL;
- ai_choose_role_unit(pplayer, pcity, choice, F_HELP_WONDER, dist / 2);
- }
- } else {
- int tech_req = get_unit_type(unit_type)->tech_requirement;
+ if (unit_type == U_LAST) {
+ /* We cannot build such units yet
+ * but we will consider it to stimulate science */
+ unit_type = get_role_unit(F_HELP_WONDER, 0);
+ }
- /* XXX (FIXME): Had to add the scientist guess here too. -- Syela */
- /* What Syela probably means is that this addition to tech want
- * is in addition to the tech want implitictly added by
- * ai_choose_rule_unit() above. - Per */
- pplayer->ai.tech_want[tech_req] += want;
- TECH_LOG(LOG_DEBUG, pplayer, tech_req, "+ %d for %s to build wonders",
- want, unit_name(unit_type));
+ /* Check if wonder needs a little help. */
+ if (build_points_left(ai->wonder_city)
+ > unit_build_shield_cost(unit_type) * caravans) {
+ Impr_Type_id wonder = ai->wonder_city->currently_building;
+ int want = ai->wonder_city->ai.building_want[wonder];
+ int dist = pcity->ai.distance_to_wonder_city /
+ get_unit_type(unit_type)->move_rate;
+
+ want /= MAX(dist, 1);
+ CITY_LOG(LOG_DEBUG, pcity, "want %s to help wonder in %s with %d",
+ unit_name(unit_type), ai->wonder_city->name, want);
+ if (want > choice->want) {
+ /* This sets our tech want in cases where we cannot actually build
+ * the unit. */
+ unit_type = ai_wants_role_unit(pplayer, pcity, F_HELP_WONDER, want);
+ if (can_build_unit(pcity, unit_type)) {
+ choice->want = want;
+ choice->type = CT_NONMIL;
+ choice->choice = unit_type;
+ } else {
+ CITY_LOG(LOG_DEBUG, pcity, "would but could not build %s, bumped reqs",
+ unit_name(unit_type));
}
}
- } city_list_iterate_end;
+ }
}
/**************************************************************************
@@ -150,6 +133,7 @@
void domestic_advisor_choose_build(struct player *pplayer, struct city *pcity,
struct ai_choice *choice)
{
+ struct ai_data *ai = ai_data_get(pplayer);
/* Government of the player */
struct government *gov = get_gov_pplayer(pplayer);
/* Unit type with certain role */
@@ -161,11 +145,17 @@
unit_type = best_role_unit(pcity, F_SETTLERS);
if (unit_type != U_LAST
+ && (pcity != ai->wonder_city
+ || get_unit_type(unit_type)->pop_cost == 0)
&& pcity->surplus[O_FOOD] > utype_upkeep_cost(get_unit_type(unit_type),
gov, O_FOOD)) {
/* settler_want calculated in settlers.c called from ai_manage_cities() */
int want = pcity->ai.settler_want;
+ if (ai->wonder_city == pcity) {
+ want /= 5;
+ }
+
/* Allowing multiple settlers per city now. I think this is correct.
* -- Syela */
@@ -184,11 +174,17 @@
unit_type = best_role_unit(pcity, F_CITIES);
if (unit_type != U_LAST
+ && (pcity != ai->wonder_city
+ || get_unit_type(unit_type)->pop_cost == 0)
&& pcity->surplus[O_FOOD] >= utype_upkeep_cost(get_unit_type(unit_type),
gov, O_FOOD)) {
/* founder_want calculated in settlers.c, called from ai_manage_cities().
*/
int want = pcity->ai.founder_want;
+ if (ai->wonder_city == pcity) {
+ want /= 5;
+ }
+
if (want > choice->want) {
CITY_LOG(LOG_DEBUG, pcity, "desires founders with passion %d", want);
choice->want = want;
@@ -217,7 +213,7 @@
init_choice(&cur);
/* Consider building caravan-type units to aid wonder construction */
- ai_choose_help_wonder(pcity, &cur);
+ ai_choose_help_wonder(pcity, &cur, ai);
copy_if_better_choice(&cur, choice);
init_choice(&cur);
Index: ai/advmilitary.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v
retrieving revision 1.185
diff -u -r1.185 advmilitary.c
--- ai/advmilitary.c 3 Feb 2005 09:48:53 -0000 1.185
+++ ai/advmilitary.c 15 Feb 2005 12:07:31 -0000
@@ -1236,6 +1236,7 @@
void military_advisor_choose_build(struct player *pplayer, struct city *pcity,
struct ai_choice *choice)
{
+ struct ai_data *ai = ai_data_get(pplayer);
Unit_Type_id unit_type;
unsigned int our_def, danger, urgency;
struct tile *ptile = pcity->tile;
@@ -1252,6 +1253,10 @@
freelog(LOG_DEBUG, "%s: danger = %d, grave_danger = %d, our_def = %d",
pcity->name, pcity->ai.danger, pcity->ai.grave_danger, our_def);
+ if (pcity == ai->wonder_city && pcity->ai.grave_danger == 0) {
+ return; /* Other cities can build our defenders, thank you! */
+ }
+
ai_choose_diplomat_defensive(pplayer, pcity, choice, our_def);
/* Otherwise no need to defend yet */
@@ -1352,7 +1357,8 @@
} /* ok, don't need to defend */
if (pcity->surplus[O_SHIELD] <= 0
- || pcity->ppl_unhappy[4] > pcity->ppl_unhappy[2]) {
+ || pcity->ppl_unhappy[4] > pcity->ppl_unhappy[2]
+ || pcity == ai->wonder_city) {
/* Things we consider below are not life-saving so we don't want to
* build them if our populace doesn't feel like it */
return;
Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.194
diff -u -r1.194 aicity.c
--- ai/aicity.c 14 Feb 2005 21:47:35 -0000 1.194
+++ ai/aicity.c 15 Feb 2005 12:07:31 -0000
@@ -34,6 +34,9 @@
#include "support.h"
#include "unit.h"
+#include "path_finding.h"
+#include "pf_tools.h"
+
#include "cityhand.h"
#include "citytools.h"
#include "cityturn.h"
@@ -563,15 +566,127 @@
/* Reduce want if building gets obsoleted soon */
if (tech_exists(pimpr->obsolete_by)) {
v -= v / MAX(1, num_unknown_techs_for_goal(pplayer, pimpr->obsolete_by));
- }
+ }
/* Adjust by building cost */
v -= pimpr->build_cost / (pcity->surplus[O_SHIELD] * 10 + 1);
+ /* Would it mean losing shields? */
+ if ((pcity->is_building_unit
+ || (is_wonder(pcity->currently_building)
+ && !is_wonder(id))
+ || (!is_wonder(pcity->currently_building)
+ && is_wonder(id)))
+ && pcity->turn_last_built != game.turn) {
+ v -= (pcity->shield_stock / 2) * (SHIELD_WEIGHTING / 2);
+ }
+
+ /* Are we wonder city? Try to avoid building non-wonders very much. */
+ if (pcity == ai->wonder_city && !is_wonder(id)) {
+ v /= 5;
+ }
+
/* Set */
pcity->ai.building_want[id] = v;
}
+/**************************************************************************
+ Calculate walking distance to nearest friendly cities from every city.
+
+ The hidden assumption here is that a F_HELP_WONDER unit is like any
+ other unit that will use this data.
+
+ pcity->ai.downtown is set to the number of cities within 4 turns of
+ the best help wonder unit we can currently produce.
+**************************************************************************/
+static void calculate_city_clusters(struct player *pplayer)
+{
+ struct pf_map *map;
+ struct pf_parameter parameter;
+ Unit_Type_id unittype;
+ struct unit *ghost;
+ int range;
+
+ city_list_iterate(pplayer->cities, pcity) {
+ pcity->ai.downtown = 0;
+ } city_list_iterate_end;
+
+ unittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
+ if (unittype == U_LAST) {
+ unittype = get_role_unit(F_HELP_WONDER, 0); /* simulate future unit */
+ if (unittype == U_LAST) {
+ return; /* ruleset has no help wonder unit */
+ }
+ }
+ ghost = create_unit_virtual(pplayer, NULL, unittype, 0);
+ range = unit_move_rate(ghost) * 4;
+
+ city_list_iterate(pplayer->cities, pcity) {
+ ghost->tile = pcity->tile;
+ pft_fill_unit_parameter(¶meter, ghost);
+ map = pf_create_map(¶meter);
+
+ pf_iterator(map, pos) {
+ struct city *acity = map_get_city(pos.tile);
+
+ if (pos.total_MC > range) {
+ break;
+ }
+ if (!acity) {
+ continue;
+ }
+ if (city_owner(acity) == pplayer) {
+ pcity->ai.downtown++;
+ }
+ } pf_iterator_end;
+ } city_list_iterate_end;
+
+ destroy_unit_virtual(ghost);
+}
+
+/**************************************************************************
+ Calculate walking distances to wonder city from nearby cities.
+**************************************************************************/
+static void calculate_wonder_helpers(struct player *pplayer,
+ struct ai_data *ai)
+{
+ struct pf_map *map;
+ struct pf_parameter parameter;
+ Unit_Type_id unittype;
+ struct unit *ghost;
+ int maxrange;
+
+ city_list_iterate(pplayer->cities, acity) {
+ acity->ai.distance_to_wonder_city = 0; /* unavailable */
+ } city_list_iterate_end;
+
+ unittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
+ if (unittype == U_LAST) {
+ return;
+ }
+ ghost = create_unit_virtual(pplayer, ai->wonder_city, unittype, 0);
+ maxrange = unit_move_rate(ghost) * 7;
+
+ pft_fill_unit_parameter(¶meter, ghost);
+ map = pf_create_map(¶meter);
+
+ pf_iterator(map, pos) {
+ struct city *acity = map_get_city(pos.tile);
+
+ if (pos.total_MC > maxrange) {
+ break;
+ }
+ if (!acity) {
+ continue;
+ }
+ if (city_owner(acity) == pplayer) {
+ acity->ai.distance_to_wonder_city = pos.total_MC;
+ }
+ } pf_iterator_end;
+
+ destroy_unit_virtual(ghost);
+}
+
/**************************************************************************
Prime pcity->ai.building_want[]
**************************************************************************/
@@ -581,6 +696,63 @@
{
struct ai_data *ai = ai_data_get(pplayer);
+ /* Preliminary analysis - find our Wonder City. Also check if it
+ * is sane to continue building the wonder in it. If either does
+ * not check out, make a Wonder City. */
+ if (!(ai->wonder_city != NULL
+ && ai->wonder_city->surplus[O_SHIELD] > 0
+ && !ai->wonder_city->is_building_unit
+ && is_wonder(ai->wonder_city->currently_building)
+ && can_build_improvement(ai->wonder_city,
+ ai->wonder_city->currently_building)
+ && !improvement_obsolete(pplayer, ai->wonder_city->currently_building)
+ && !is_building_replaced(ai->wonder_city,
+ ai->wonder_city->currently_building))
+ || ai->wonder_city == NULL) {
+ /* Find a new wonder city! */
+ int best_candidate_value = 0;
+ struct city *best_candidate = NULL;
+ /* Whether ruleset has a help wonder unit type */
+ bool has_help = (get_role_unit(F_HELP_WONDER, 0) != U_LAST);
+
+ calculate_city_clusters(pplayer);
+
+ city_list_iterate(pplayer->cities, pcity) {
+ int value = pcity->surplus[O_SHIELD];
+
+ if (pcity->ai.grave_danger > 0) {
+ continue;
+ }
+ if (is_ocean_near_tile(pcity->tile)) {
+ value /= 2;
+ }
+ /* Downtown is the number of cities within a certain pf range.
+ * These may be able to help with caravans. Also look at the whole
+ * continent. */
+ if (first_role_unit_for_player(pplayer, F_HELP_WONDER) != U_LAST) {
+ value += pcity->ai.downtown;
+ value += ai->stats.cities[pcity->tile->continent] / 8;
+ }
+ if (ai->threats.continent[pcity->tile->continent] > 0) {
+ /* We have threatening neighbours: -25% */
+ value -= value / 4;
+ }
+ /* Require that there is at least some neighbors for wonder helpers,
+ * if ruleset supports it. */
+ if (value > best_candidate_value
+ && (!has_help || ai->stats.cities[pcity->tile->continent] > 5)
+ && (!has_help || pcity->ai.downtown > 3)) {
+ best_candidate = pcity;
+ best_candidate_value = value;
+ }
+ } city_list_iterate_end;
+ if (best_candidate) {
+ CITY_LOG(LOG_DEBUG, best_candidate, "chosen as wonder-city!");
+ ai->wonder_city = best_candidate;
+ }
+ }
+ calculate_wonder_helpers(pplayer, ai);
+
/* First find current worth of cities and cache this. */
city_list_iterate(pplayer->cities, acity) {
acity->ai.worth = city_want(pplayer, acity, ai);
@@ -592,13 +764,16 @@
continue;
}
city_list_iterate(pplayer->cities, pcity) {
+ if (pcity != ai->wonder_city && is_wonder(id)) {
+ /* Only wonder city should build wonders! */
+ continue;
+ }
if (pplayer->ai.control && pcity->ai.next_recalc > game.turn) {
continue; /* do not recalc yet */
} else {
pcity->ai.building_want[id] = 0; /* do recalc */
}
if (city_got_building(pcity, id)
- || pcity->surplus[O_SHIELD] == 0
|| !can_build_improvement(pcity, id)
|| is_building_replaced(pcity, id)) {
continue; /* Don't build redundant buildings */
@@ -619,47 +794,6 @@
} city_list_iterate_end;
}
-/***************************************************************************
- This function computes distances between cities for purpose of building
- crowds of water-consuming Caravans or smoggish Freights which want to add
- their brick to the wonder being built in pcity.
-
- At the function entry point, our warmap is intact. We need to do two
- things: (1) establish "downtown" for THIS city (which is an estimate of
- how much help we can expect when building a wonder) and
- (2) establish distance to pcity for ALL cities on our continent.
-
- If there are more than one wondercity, things will get a bit random.
-****************************************************************************/
-static void establish_city_distances(struct player *pplayer,
- struct city *pcity)
-{
- int distance;
- Continent_id wonder_continent;
- Unit_Type_id freight = best_role_unit(pcity, F_HELP_WONDER);
- int moverate = (freight == U_LAST) ? SINGLE_MOVE
- : get_unit_type(freight)->move_rate;
-
- if (!pcity->is_building_unit && is_wonder(pcity->currently_building)) {
- wonder_continent = map_get_continent(pcity->tile);
- } else {
- wonder_continent = 0;
- }
-
- pcity->ai.downtown = 0;
- city_list_iterate(pplayer->cities, othercity) {
- distance = WARMAP_COST(othercity->tile);
- if (wonder_continent != 0
- && map_get_continent(othercity->tile) == wonder_continent) {
- othercity->ai.distance_to_wonder_city = distance;
- }
-
- /* How many people near enough would help us? */
- distance += moverate - 1; distance /= moverate;
- pcity->ai.downtown += MAX(0, 5 - distance);
- } city_list_iterate_end;
-}
-
/**************************************************************************
Choose a build for the barbarian player.
@@ -740,8 +874,8 @@
/* Fallbacks */
if (pcity->ai.choice.want == 0) {
/* Fallbacks do happen with techlevel 0, which is now default. -- Per */
- CITY_LOG(LOG_VERBOSE, pcity, "Falling back - didn't want to build
soldiers,"
- " settlers, or buildings");
+ CITY_LOG(LOG_ERROR, pcity, "Falling back - didn't want to build soldiers,"
+ " workers, caravans, settlers, or buildings!");
pcity->ai.choice.want = 1;
if (best_role_unit(pcity, F_TRADE_ROUTE) != U_LAST) {
pcity->ai.choice.choice = best_role_unit(pcity, F_TRADE_ROUTE);
@@ -753,7 +887,7 @@
pcity->ai.choice.choice = best_role_unit(pcity, F_SETTLERS);
pcity->ai.choice.type = CT_NONMIL;
} else {
- CITY_LOG(LOG_VERBOSE, pcity, "Cannot even build a fallback "
+ CITY_LOG(LOG_ERROR, pcity, "Cannot even build a fallback "
"(caravan/coinage/settlers). Fix the ruleset!");
pcity->ai.choice.want = 0;
}
@@ -790,10 +924,6 @@
}
pcity->currently_building = pcity->ai.choice.choice;
pcity->is_building_unit = is_unit_choice_type(pcity->ai.choice.type);
-
- /* Help other cities to send caravans to us */
- generate_warmap(pcity, NULL);
- establish_city_distances(pplayer, pcity);
} else {
pcity->currently_building = pcity->ai.choice.choice;
pcity->is_building_unit = is_unit_choice_type(pcity->ai.choice.type);
@@ -1037,10 +1167,6 @@
city_list_iterate(pplayer->cities, pcity) {
/* Note that this function mungs the seamap, but we don't care */
military_advisor_choose_build(pplayer, pcity, &pcity->ai.choice);
- /* because establish_city_distances doesn't need the seamap
- * it determines downtown and distance_to_wondercity,
- * which ai_city_choose_build will need */
- establish_city_distances(pplayer, pcity);
/* Will record its findings in pcity->settler_want */
contemplate_terrain_improvements(pcity);
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.51
diff -u -r1.51 aidata.c
--- ai/aidata.c 9 Feb 2005 08:45:42 -0000 1.51
+++ ai/aidata.c 15 Feb 2005 12:07:31 -0000
@@ -468,6 +468,7 @@
memset(ai->government_want, 0,
(game.government_count + 1) * sizeof(*ai->government_want));
+ ai->wonder_city = NULL;
ai->diplomacy.target = NULL;
ai->diplomacy.strategy = WIN_OPEN;
ai->diplomacy.timer = 0;
Index: ai/aidata.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.h,v
retrieving revision 1.22
diff -u -r1.22 aidata.h
--- ai/aidata.h 9 Feb 2005 08:45:42 -0000 1.22
+++ ai/aidata.h 15 Feb 2005 12:07:31 -0000
@@ -56,6 +56,9 @@
BV_DEFINE(bv_id, MAX_NUM_ID);
struct ai_data {
+ /* The Wonder City */
+ struct city *wonder_city;
+
/* Precalculated info about city improvements */
enum ai_improvement_status impr_calc[MAX_NUM_ITEMS];
enum req_range impr_range[MAX_NUM_ITEMS];
@@ -104,7 +107,7 @@
int triremes;
int units[UCL_LAST + 1]; /* no. units by class */
int *workers; /* cities to workers on continent*/
- int *cities; /* number of cities on continent */
+ int *cities; /* number of cities we have on continent */
int passengers; /* number of passengers waiting for boats */
int boats;
int available_boats;
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.136
diff -u -r1.136 aitools.c
--- ai/aitools.c 3 Feb 2005 09:48:53 -0000 1.136
+++ ai/aitools.c 15 Feb 2005 12:07:31 -0000
@@ -700,82 +700,28 @@
}
/**************************************************************************
- Returns TRUE if pcity's owner is building any wonder in another city on
- the same continent (if so, we may want to build a caravan here).
-**************************************************************************/
-static bool is_building_other_wonder(struct city *pcity)
-{
- struct player *pplayer = city_owner(pcity);
-
- city_list_iterate(pplayer->cities, acity) {
- if (pcity != acity
- && !acity->is_building_unit
- && is_wonder(acity->currently_building)
- && (map_get_continent(acity->tile)
- == map_get_continent(pcity->tile))) {
- return TRUE;
- }
- } city_list_iterate_end;
-
- return FALSE;
-}
-
-/**************************************************************************
Choose improvement we like most and put it into ai_choice.
- TODO: Clean, update the log calls.
+
+ "I prefer the ai_choice as a return value; gcc prefers it as an arg"
+ -- Syela
**************************************************************************/
void ai_advisor_choose_building(struct city *pcity, struct ai_choice *choice)
-{ /* I prefer the ai_choice as a return value; gcc prefers it as an arg --
Syela */
+{
Impr_Type_id id = B_LAST;
- unsigned int danger = 0;
- int downtown = 0, cities = 0;
- int want=0;
- struct player *plr;
-
- plr = city_owner(pcity);
-
- /* too bad plr->score isn't kept up to date. */
- city_list_iterate(plr->cities, acity)
- danger += acity->ai.danger;
- downtown += acity->ai.downtown;
- cities++;
- city_list_iterate_end;
+ int want = 0;
+ struct player *plr = city_owner(pcity);
impr_type_iterate(i) {
if (!plr->ai.control && is_wonder(i)) {
continue; /* Humans should not be advised to build wonders or palace */
}
- if (!is_wonder(i)
- || (!pcity->is_building_unit && is_wonder(pcity->currently_building)
- && pcity->shield_stock >= impr_build_shield_cost(i) / 2)
- || (!is_building_other_wonder(pcity)
- /* otherwise caravans will be killed! */
- && pcity->ai.grave_danger == 0
- && pcity->ai.downtown * cities >= downtown
- && pcity->ai.danger * cities <= danger)) {
- /* Is this too many restrictions? */
- /* trying to keep wonders in safe places with easy caravan
- * access -- Syela */
- if(pcity->ai.building_want[i]>want) {
- /* we have to do the can_build check to avoid Built Granary.
- * Now Building Granary. */
- if (can_build_improvement(pcity, i)) {
- want = pcity->ai.building_want[i];
- id = i;
- } else {
- freelog(LOG_DEBUG, "%s can't build %s", pcity->name,
- get_improvement_name(i));
- }
- } /* id is the building we like the best */
+ if (pcity->ai.building_want[i] > want
+ && can_build_improvement(pcity, i)) {
+ want = pcity->ai.building_want[i];
+ id = i;
}
} impr_type_iterate_end;
- if (want != 0) {
- freelog(LOG_DEBUG, "AI_Chosen: %s with desire = %d for %s",
- get_improvement_name(id), want, pcity->name);
- } else {
- freelog(LOG_DEBUG, "AI_Chosen: None for %s", pcity->name);
- }
choice->want = want;
choice->choice = id;
choice->type = CT_BUILDING;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#12262) Fix AI wonder building,
Per I. Mathisen <=
|
|