Freeciv21
Develop your civilization from humble roots to a global empire
advbuilding.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // common
15 #include "ai.h"
16 #include "city.h"
17 #include "game.h"
18 #include "movement.h"
19 #include "player.h"
20 #include "specialist.h"
21 
22 /* common/aicore */
23 #include "path_finding.h"
24 #include "pf_tools.h"
25 
26 // server
27 #include "citytools.h"
28 #include "srv_log.h"
29 
30 /* server/advisors */
31 #include "advdata.h"
32 #include "infracache.h" // adv_city
33 
34 // ai
35 #include "handicaps.h"
36 
37 #include "advbuilding.h"
38 
48 static void calculate_city_clusters(struct player *pplayer)
49 {
50  struct unit_type *punittype;
51  struct unit *ghost;
52  int range;
53 
54  city_list_iterate(pplayer->cities, pcity)
55  {
56  pcity->server.adv->downtown = 0;
57  }
59 
60  if (num_role_units(action_id_get_role(ACTION_HELP_WONDER)) == 0) {
61  return; // ruleset has no help wonder unit
62  }
63 
64  punittype = best_role_unit_for_player(
65  pplayer, action_id_get_role(ACTION_HELP_WONDER));
66 
67  if (!punittype) {
68  // simulate future unit
69  punittype = get_role_unit(action_id_get_role(ACTION_HELP_WONDER), 0);
70  }
71 
72  fc_assert_msg(utype_can_do_action(punittype, ACTION_HELP_WONDER),
73  "Non existence of wonder helper unit not caught");
74 
75  ghost = unit_virtual_create(pplayer, nullptr, punittype, 0);
76  range = unit_move_rate(ghost) * 4;
77 
78  city_list_iterate(pplayer->cities, pcity)
79  {
80  struct pf_parameter parameter;
81  struct pf_map *pfm;
82  struct adv_city *city_data = pcity->server.adv;
83 
84  unit_tile_set(ghost, pcity->tile);
85  pft_fill_unit_parameter(&parameter, ghost);
86  parameter.omniscience = !has_handicap(pplayer, H_MAP);
87  pfm = pf_map_new(&parameter);
88 
89  pf_map_move_costs_iterate(pfm, ptile, move_cost, false)
90  {
91  struct city *acity = tile_city(ptile);
92 
93  if (move_cost > range) {
94  break;
95  }
96  if (!acity) {
97  continue;
98  }
99  if (city_owner(acity) == pplayer) {
100  city_data->downtown++;
101  }
102  }
104 
105  pf_map_destroy(pfm);
106  }
108 
109  unit_virtual_destroy(ghost);
110 }
111 
115 static void ba_human_wants(struct player *pplayer, struct city *wonder_city)
116 {
117  /* Clear old building wants.
118  * Do this separately from the iteration over improvement types
119  * because each iteration could actually update more than one improvement,
120  * if improvements have improvements as requirements.
121  */
122  city_list_iterate(pplayer->cities, pcity)
123  {
124  // For a human player, any building is worth building until discarded
125  improvement_iterate(pimprove)
126  {
127  pcity->server.adv->building_want[improvement_index(pimprove)] = 1;
128  }
130  }
132 
133  improvement_iterate(pimprove)
134  {
135  const bool is_coinage = improvement_has_flag(pimprove, IF_GOLD);
136 
137  // Handle coinage specially because you can never complete coinage
138  if (is_coinage
139  || can_player_build_improvement_later(pplayer, pimprove)) {
140  city_list_iterate(pplayer->cities, pcity)
141  {
142  if (pcity != wonder_city && is_wonder(pimprove)) {
143  // Only wonder city should build wonders!
144  pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
145  } else if (!is_coinage
146  && (!can_city_build_improvement_later(pcity, pimprove)
147  || (!is_improvement_productive(pcity, pimprove)))) {
148  // Don't consider impossible or unproductive buildings
149  pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
150  } else if (city_has_building(pcity, pimprove)) {
151  // Never want to build something we already have.
152  pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
153  }
154  // else wait until a later turn
155  }
157  } else {
158  // An impossible improvement
159  city_list_iterate(pplayer->cities, pcity)
160  {
161  pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
162  }
164  }
165  }
167 
168 #ifdef FREECIV_DEBUG
169  // This logging is relatively expensive, so activate only if necessary
170  city_list_iterate(pplayer->cities, pcity)
171  {
172  improvement_iterate(pimprove)
173  {
174  if (pcity->server.adv->building_want[improvement_index(pimprove)]
175  != 0) {
176  CITY_LOG(
177  LOG_DEBUG, pcity, "want to build %s with " ADV_WANT_PRINTF,
178  improvement_rule_name(pimprove),
179  pcity->server.adv->building_want[improvement_index(pimprove)]);
180  }
181  }
183  }
185 #endif // FREECIV_DEBUG
186 }
187 
191 void building_advisor(struct player *pplayer)
192 {
193  struct adv_data *adv = adv_data_get(pplayer, nullptr);
194  struct city *wonder_city = game_city_by_number(adv->wonder_city);
195 
196  CALL_FUNC_EACH_AI(build_adv_init, pplayer);
197 
198  if (wonder_city && city_owner(wonder_city) != pplayer) {
199  // We lost it to the enemy!
200  adv->wonder_city = 0;
201  wonder_city = nullptr;
202  }
203 
204  /* Preliminary analysis - find our Wonder City. Also check if it
205  * is sane to continue building the wonder in it. If either does
206  * not check out, make a Wonder City. */
207  if (nullptr == wonder_city || 0 >= wonder_city->surplus[O_SHIELD]
208  || VUT_UTYPE == wonder_city->production.kind // changed to defender?
209  || !is_wonder(wonder_city->production.value.building)
211  wonder_city, wonder_city->production.value.building)
213  wonder_city, wonder_city->production.value.building)) {
214  // Find a new wonder city!
215  int best_candidate_value = 0;
216  struct city *best_candidate = nullptr;
217  // Whether ruleset has a help wonder unit type
218  bool has_help =
219  (num_role_units(action_id_get_role(ACTION_HELP_WONDER)) > 0);
220 
221  calculate_city_clusters(pplayer);
222 
223  city_list_iterate(pplayer->cities, pcity)
224  {
225  int value = pcity->surplus[O_SHIELD];
226  Continent_id place = tile_continent(pcity->tile);
227  struct adv_city *city_data = pcity->server.adv;
228 
229  if (is_ai(pplayer)) {
230  bool result = true;
231 
232  /* AI has opportunity to say that this city cannot be
233  * wonder city */
234  CALL_PLR_AI_FUNC(consider_wonder_city, pplayer, pcity, &result);
235  if (!result) {
236  continue;
237  }
238  }
239 
240  if (is_terrain_class_near_tile(pcity->tile, TC_OCEAN)) {
241  value /= 2;
242  }
243  /* Downtown is the number of cities within a certain pf range.
244  * These may be able to help with caravans. Also look at the whole
245  * continent. */
247  pplayer, action_id_get_role(ACTION_HELP_WONDER))) {
248  value += city_data->downtown;
249 
250  if (place >= 0) {
251  value += adv->stats.cities[place] / 8;
252  }
253  }
254  if (place >= 0 && adv->threats.continent[place] > 0) {
255  // We have threatening neighbours: -25%
256  value -= value / 4;
257  }
258  /* Require that there is at least some neighbors for wonder helpers,
259  * if ruleset supports it. */
260  if (value > best_candidate_value
261  && (!has_help || (place >= 0 && adv->stats.cities[place] > 5))
262  && (!has_help || city_data->downtown > 3)) {
263  best_candidate = pcity;
264  best_candidate_value = value;
265  }
266  }
268  if (best_candidate) {
269  CITY_LOG(LOG_DEBUG, best_candidate, "chosen as wonder-city!");
270  adv->wonder_city = best_candidate->id;
271  wonder_city = best_candidate;
272  }
273  }
274 
275  if (is_ai(pplayer)) {
276  CALL_PLR_AI_FUNC(build_adv_prepare, pplayer, pplayer, adv);
277  CALL_PLR_AI_FUNC(build_adv_adjust_want, pplayer, pplayer, wonder_city);
278  } else {
279  ba_human_wants(pplayer, wonder_city);
280  }
281 }
282 
286 void building_advisor_choose(struct city *pcity, struct adv_choice *choice)
287 {
288  struct player *plr = city_owner(pcity);
289  struct impr_type *chosen = nullptr;
290  int want = 0;
291 
292  improvement_iterate(pimprove)
293  {
294  if (is_wonder(pimprove)) {
295  continue; // Humans should not be advised to build wonders or palace
296  }
297  if (pcity->server.adv->building_want[improvement_index(pimprove)] > want
298  && can_city_build_improvement_now(pcity, pimprove)) {
299  want = pcity->server.adv->building_want[improvement_index(pimprove)];
300  chosen = pimprove;
301  }
302  }
304 
305  choice->want = want;
306  choice->value.building = chosen;
307 
308  if (chosen) {
309  choice->type = CT_BUILDING;
310 
311  CITY_LOG(LOG_DEBUG, pcity, "wants most to build %s at %d",
312  improvement_rule_name(chosen), want);
313  } else {
314  choice->type = CT_NONE;
315  }
316  choice->need_boat = false;
317 
318  // Allow ai to override
319  CALL_PLR_AI_FUNC(choose_building, plr, pcity, choice);
320 }
321 
325 void advisor_choose_build(struct player *pplayer, struct city *pcity)
326 {
327  struct adv_choice choice;
328 
329  building_advisor_choose(pcity, &choice);
330 
331  if (valid_improvement(choice.value.building)) {
332  struct universal target = {.value = {.building = choice.value.building},
333  .kind = VUT_IMPROVEMENT};
334 
335  change_build_target(pplayer, pcity, &target, E_IMP_AUTO);
336  return;
337  }
338 
339  // Build the first thing we can think of (except moving small wonder).
340  improvement_iterate(pimprove)
341  {
342  if (can_city_build_improvement_now(pcity, pimprove)
343  && pimprove->genus != IG_SMALL_WONDER) {
344  struct universal target = {.value = {.building = pimprove},
345  .kind = VUT_IMPROVEMENT};
346 
347  change_build_target(pplayer, pcity, &target, E_IMP_AUTO);
348  return;
349  }
350  }
352 }
#define action_id_get_role(act_id)
Definition: actions.h:580
static void calculate_city_clusters(struct player *pplayer)
Calculate walking distance to nearest friendly cities from every city.
Definition: advbuilding.cpp:48
void building_advisor(struct player *pplayer)
Prime pcity->server.adv.building_want[].
static void ba_human_wants(struct player *pplayer, struct city *wonder_city)
Set building wants for human player.
void building_advisor_choose(struct city *pcity, struct adv_choice *choice)
Choose improvement we like most and put it into adv_choice.
void advisor_choose_build(struct player *pplayer, struct city *pcity)
Setup improvement building.
@ CT_NONE
Definition: advchoice.h:23
@ CT_BUILDING
Definition: advchoice.h:24
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Return a pointer to our data.
Definition: advdata.cpp:591
#define CALL_FUNC_EACH_AI(_func,...)
Definition: ai.h:393
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition: ai.h:383
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Return TRUE iff the city has this building in it.
Definition: city.cpp:1189
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Return whether given city can build given building; returns FALSE if the building is obsolete.
Definition: city.cpp:815
bool can_city_build_improvement_later(const struct city *pcity, const struct impr_type *pimprove)
Return whether player can eventually build given building in the city; returns FALSE if improvement c...
Definition: city.cpp:832
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
#define city_list_iterate_end
Definition: city.h:484
void change_build_target(struct player *pplayer, struct city *pcity, struct universal *target, enum event_type event)
Change the build target.
Definition: citytools.cpp:2986
#define ADV_WANT_PRINTF
Definition: fc_types.h:1145
@ O_SHIELD
Definition: fc_types.h:86
signed short Continent_id
Definition: fc_types.h:289
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
AI players may have handicaps - allowing them to cheat or preventing them from using certain algorith...
Definition: handicaps.cpp:62
@ H_MAP
Definition: handicaps.h:27
const char * improvement_rule_name(const struct impr_type *pimprove)
Return the (untranslated) rule name of the improvement.
bool can_player_build_improvement_later(const struct player *p, const struct impr_type *pimprove)
Whether player can eventually build given building somewhere – i.e., returns TRUE if building is avai...
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
Returns pointer when the improvement_type "exists" in this game, returns nullptr otherwise.
Impr_type_id improvement_index(const struct impr_type *pimprove)
Return the improvement index.
bool is_wonder(const struct impr_type *pimprove)
Returns whether improvement is some kind of wonder.
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Return TRUE if the impr has this flag otherwise FALSE.
bool is_improvement_productive(const struct city *pcity, const struct impr_type *pimprove)
Returns TRUE if an improvement in a city is productive, in some way.
#define improvement_iterate_end
Definition: improvement.h:199
#define improvement_iterate(_p)
Definition: improvement.h:193
#define fc_assert_msg(condition, message,...)
Definition: log.h:96
constexpr auto LOG_DEBUG
Definition: log.h:27
int unit_move_rate(const struct unit *punit)
This function calculates the move rate of the unit.
Definition: movement.cpp:78
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Factory function to create a new map according to the parameter.
void pf_map_destroy(struct pf_map *pfm)
After usage the map must be destroyed.
#define pf_map_move_costs_iterate_end
Definition: path_finding.h:542
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
Definition: path_finding.h:532
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct unit *punit)
Fill classic parameters for an unit.
Definition: pf_tools.cpp:822
#define is_ai(plr)
Definition: player.h:227
#define CITY_LOG(_, pcity, msg,...)
Definition: srv_log.h:80
enum choice_type type
Definition: advchoice.h:32
adv_want want
Definition: advchoice.h:34
universals_u value
Definition: advchoice.h:33
bool need_boat
Definition: advchoice.h:35
int downtown
Definition: infracache.h:31
struct adv_data::@85 threats
int * cities
Definition: advdata.h:86
struct adv_data::@87 stats
bool * continent
Definition: advdata.h:55
int wonder_city
Definition: advdata.h:46
Definition: city.h:291
int surplus[O_LAST]
Definition: city.h:324
int id
Definition: city.h:296
struct universal production
Definition: city.h:368
struct adv_city * adv
Definition: city.h:422
struct city::@15::@17 server
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
Definition: unit.h:134
struct tile * tile
Definition: unit.h:136
enum universals_n kind
Definition: fc_types.h:740
universals_u value
Definition: fc_types.h:739
bool is_terrain_class_near_tile(const struct tile *ptile, enum terrain_class tclass)
Is there terrain of the given class near tile? (Does not check ptile itself.)
Definition: terrain.cpp:495
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_continent(_tile)
Definition: tile.h:74
const struct impr_type * building
Definition: fc_types.h:579
void unit_virtual_destroy(struct unit *punit)
Free the memory used by virtual unit.
Definition: unit.cpp:1588
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Create a virtual unit skeleton.
Definition: unit.cpp:1490
void unit_tile_set(struct unit *punit, struct tile *ptile)
Set the tile location of the unit.
Definition: unit.cpp:1200
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Return "best" unit the player can build, with given role/flag.
Definition: unittype.cpp:1950
int num_role_units(int role)
How many unit types have specified role/flag.
Definition: unittype.cpp:1866
struct unit_type * get_role_unit(int role, int role_index)
Return index-th unit with specified role/flag.
Definition: unittype.cpp:1900
struct unit_type * first_role_unit_for_player(const struct player *pplayer, int role)
Return first unit the player can build, with given role/flag.
Definition: unittype.cpp:1976
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Return TRUE iff units of the given type can do the specified generalized (ruleset defined) action ena...
Definition: unittype.cpp:386