Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/advisors/advbuilding.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
advbuilding.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "rand.h"
20
21/* common */
22#include "ai.h"
23#include "city.h"
24#include "effects.h"
25#include "game.h"
26#include "movement.h"
27#include "player.h"
28#include "specialist.h"
29
30/* common/aicore */
31#include "path_finding.h"
32#include "pf_tools.h"
33
34/* server */
35#include "citytools.h"
36#include "plrhand.h"
37#include "srv_log.h"
38
39/* server/advisors */
40#include "advdata.h"
41#include "advtools.h"
42#include "infracache.h" /* adv_city */
43
44/* ai */
45#include "handicaps.h"
46
47#include "advbuilding.h"
48
49/**********************************************************************/
58 static void calculate_city_clusters(struct player *pplayer)
59{
60 struct unit_type *punittype;
61 struct unit *ghost;
62 int range;
63 const struct civ_map *nmap = &(wld.map);
64
65 city_list_iterate(pplayer->cities, pcity) {
66 pcity->server.adv->downtown = 0;
67 } city_list_iterate_end;
68
69 if (num_role_units(action_id_get_role(ACTION_HELP_WONDER)) == 0) {
70 return; /* Ruleset has no help wonder unit */
71 }
72
73 punittype = best_role_unit_for_player(pplayer,
74 action_id_get_role(ACTION_HELP_WONDER));
75
76 if (punittype == NULL) {
77 /* Simulate future unit */
78 punittype = get_role_unit(action_id_get_role(ACTION_HELP_WONDER), 0);
79 }
80
81 fc_assert_msg(utype_can_do_action(punittype, ACTION_HELP_WONDER),
82 "Non existence of wonder helper unit not caught");
83
84 ghost = unit_virtual_create(pplayer, NULL, punittype, 0);
85 range = unit_move_rate(ghost) * 4;
86
87 city_list_iterate(pplayer->cities, pcity) {
88 struct pf_parameter parameter;
89 struct pf_map *pfm;
90 struct adv_city *city_data = pcity->server.adv;
91
92 unit_tile_set(ghost, pcity->tile);
93 pft_fill_unit_parameter(&parameter, nmap, ghost);
94 parameter.omniscience = !has_handicap(pplayer, H_MAP);
95 pfm = pf_map_new(&parameter);
96
97 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
98 struct city *acity = tile_city(ptile);
99
100 if (move_cost > range) {
101 break;
102 }
103 if (acity == NULL) {
104 continue;
105 }
106 if (city_owner(acity) == pplayer) {
107 city_data->downtown++;
108 }
109 } pf_map_move_costs_iterate_end;
110
111 pf_map_destroy(pfm);
112 } city_list_iterate_end;
113
114 unit_virtual_destroy(ghost);
115}
116
117/**********************************************************************/
120 static void ba_human_wants(struct player *pplayer, struct city *wonder_city)
121{
122 /* Clear old building wants.
123 * Do this separately from the iteration over improvement types
124 * because each iteration could actually update more than one improvement,
125 * if improvements have improvements as requirements.
126 */
127 city_list_iterate(pplayer->cities, pcity) {
128 /* For a human player, any building is worth building until discarded */
129 improvement_iterate(pimprove) {
130 pcity->server.adv->building_want[improvement_index(pimprove)] = 1;
131 } improvement_iterate_end;
132 } city_list_iterate_end;
133
134 improvement_iterate(pimprove) {
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 if (pcity != wonder_city && is_wonder(pimprove)) {
142 /* Only wonder city should build wonders! */
143 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
144 } else if (!is_coinage
145 && (!can_city_build_improvement_later(pcity, pimprove)
146 || (!is_improvement_productive(pcity, pimprove)))) {
147 /* Don't consider impossible or unproductive buildings */
148 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
149 } else if (city_has_building(pcity, pimprove)) {
150 /* Never want to build something we already have. */
151 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
152 }
153 /* else wait until a later turn */
154 } city_list_iterate_end;
155 } else {
156 /* An impossible improvement */
157 city_list_iterate(pplayer->cities, pcity) {
158 pcity->server.adv->building_want[improvement_index(pimprove)] = 0;
159 } city_list_iterate_end;
160 }
161 } improvement_iterate_end;
162
163#ifdef FREECIV_DEBUG
164 /* This logging is relatively expensive, so activate only if necessary */
165 city_list_iterate(pplayer->cities, pcity) {
166 improvement_iterate(pimprove) {
167 if (pcity->server.adv->building_want[improvement_index(pimprove)] != 0) {
168 CITY_LOG(LOG_DEBUG, pcity, "want to build %s with " ADV_WANT_PRINTF,
169 improvement_rule_name(pimprove),
170 pcity->server.adv->building_want[improvement_index(pimprove)]);
171 }
172 } improvement_iterate_end;
173 } city_list_iterate_end;
174#endif /* FREECIV_DEBUG */
175}
176
177/**********************************************************************/
180 void building_advisor(struct player *pplayer)
181{
182 struct adv_data *adv = adv_data_get(pplayer, NULL);
183 struct city *wonder_city = game_city_by_number(adv->wonder_city);
184
185 CALL_FUNC_EACH_AI(build_adv_init, pplayer);
186
187 if (wonder_city && city_owner(wonder_city) != pplayer) {
188 /* We lost it to the enemy! */
189 adv->wonder_city = 0;
190 wonder_city = NULL;
191 }
192
193 /* Preliminary analysis - find our Wonder City. Also check if it
194 * is sane to continue building the wonder in it. If either does
195 * not check out, make a Wonder City. */
196 if (NULL == wonder_city
197 || 0 >= wonder_city->surplus[O_SHIELD]
198 || VUT_UTYPE == wonder_city->production.kind /* changed to defender? */
199 || !is_wonder(wonder_city->production.value.building)
200 || !can_city_build_improvement_now(wonder_city,
201 wonder_city->production.value.building)
202 || !is_improvement_productive(wonder_city,
203 wonder_city->production.value.building)) {
204 /* Find a new wonder city! */
205 int best_candidate_value = 0;
206 struct city *best_candidate = NULL;
207 /* Whether ruleset has a help wonder unit type */
208 bool has_help =
209 (num_role_units(action_id_get_role(ACTION_HELP_WONDER)) > 0);
210
211 calculate_city_clusters(pplayer);
212
213 city_list_iterate(pplayer->cities, pcity) {
214 int value = pcity->surplus[O_SHIELD];
215 Continent_id place = tile_continent(pcity->tile);
216 struct adv_city *city_data = pcity->server.adv;
217
218 if (is_ai(pplayer)) {
219 bool result = TRUE;
220
221 /* AI has opportunity to say that this city cannot be
222 * wonder city */
223 CALL_PLR_AI_FUNC(consider_wonder_city, pplayer, pcity, &result);
224 if (!result) {
225 continue;
226 }
227 }
228
229 if (is_terrain_class_near_tile(&(wld.map), pcity->tile, TC_OCEAN)) {
230 value /= 2;
231 }
232
233 /* Downtown is the number of cities within a certain pf range.
234 * These may be able to help with caravans. Also look at the whole
235 * continent. */
236 if (first_role_unit_for_player(pplayer,
237 action_id_get_role(ACTION_HELP_WONDER))) {
238 value += city_data->downtown;
239
240 if (place >= 0) {
241 value += adv->stats.cities[place] / 8;
242 }
243 }
244
245 if (place >= 0 && adv->threats.continent[place] > 0) {
246 /* We have threatening neighbors: -25% */
247 value -= value / 4;
248 }
249
250 /* Require that there is at least some neighbors for wonder helpers,
251 * if ruleset supports it. */
252 if (value > best_candidate_value
253 && (!has_help || (place >= 0 && adv->stats.cities[place] > 5))
254 && (!has_help || city_data->downtown > 3)) {
255 best_candidate = pcity;
256 best_candidate_value = value;
257 }
258 } city_list_iterate_end;
259
260 if (best_candidate) {
261 CITY_LOG(LOG_DEBUG, best_candidate, "chosen as wonder-city!");
262 adv->wonder_city = best_candidate->id;
263 wonder_city = best_candidate;
264 }
265 }
266
267 if (is_ai(pplayer)) {
268 CALL_PLR_AI_FUNC(build_adv_prepare, pplayer, pplayer, adv);
269 CALL_PLR_AI_FUNC(build_adv_adjust_want, pplayer, pplayer, wonder_city);
270 } else {
271 ba_human_wants(pplayer, wonder_city);
272 }
273}
274
275/**********************************************************************/
278 void building_advisor_choose(struct city *pcity, struct adv_choice *choice)
279{
280 struct player *plr = city_owner(pcity);
281 struct impr_type *chosen = NULL;
282 adv_want want = 0;
283
284 improvement_iterate(pimprove) {
285 int id;
286
287 if (is_wonder(pimprove)) {
288 continue; /* Humans should not be advised to build wonders or palace */
289 }
290
291 id = improvement_index(pimprove);
292 if (pcity->server.adv->building_want[id] > want
293 && can_city_build_improvement_now(pcity, pimprove)) {
294 want = pcity->server.adv->building_want[id];
295 chosen = pimprove;
296 }
297 } improvement_iterate_end;
298
299 choice->want = want;
300 choice->value.building = chosen;
301
302 if (chosen != NULL) {
303 choice->type = CT_BUILDING;
304
305 CITY_LOG(LOG_DEBUG, pcity, "advisor wants to build %s with want "
306 ADV_WANT_PRINTF,
307 improvement_rule_name(chosen), want);
308 } else {
309 choice->type = CT_NONE;
310 }
311 choice->need_boat = FALSE;
312
313 /* Allow AI to override */
314 CALL_PLR_AI_FUNC(choose_building, plr, pcity, choice);
315}
316
317/**********************************************************************/
320 void advisor_choose_build(struct player *pplayer, struct city *pcity)
321{
322 struct adv_choice choice;
323
324 building_advisor_choose(pcity, &choice);
325
326 if (valid_improvement(choice.value.building)) {
327 struct universal target = {
328 .kind = VUT_IMPROVEMENT,
329 .value = {.building = choice.value.building}
330 };
331
332 change_build_target(pplayer, pcity, &target, E_IMP_AUTO);
333 return;
334 }
335
336 /* Build the first thing we can think of (except moving small wonder). */
337 improvement_iterate(pimprove) {
338 if (can_city_build_improvement_now(pcity, pimprove)
339 && pimprove->genus != IG_SMALL_WONDER) {
340 struct universal target = {
341 .kind = VUT_IMPROVEMENT,
342 .value = {.building = pimprove}
343 };
344
345 change_build_target(pplayer, pcity, &target, E_IMP_AUTO);
346 return;
347 }
348 } improvement_iterate_end;
349}
action_id_get_role
#define action_id_get_role(act_id)
Definition actions.h:708
calculate_city_clusters
static void calculate_city_clusters(struct player *pplayer)
Definition advbuilding.c:58
building_advisor
void building_advisor(struct player *pplayer)
Definition advbuilding.c:180
ba_human_wants
static void ba_human_wants(struct player *pplayer, struct city *wonder_city)
Definition advbuilding.c:120
building_advisor_choose
void building_advisor_choose(struct city *pcity, struct adv_choice *choice)
Definition advbuilding.c:278
advisor_choose_build
void advisor_choose_build(struct player *pplayer, struct city *pcity)
Definition advbuilding.c:320
advbuilding.h
CT_NONE
@ CT_NONE
Definition advchoice.h:37
CT_BUILDING
@ CT_BUILDING
Definition advchoice.h:38
adv_data_get
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:593
advdata.h
advtools.h
ai.h
CALL_FUNC_EACH_AI
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:384
CALL_PLR_AI_FUNC
#define CALL_PLR_AI_FUNC(_func, _player,...)
Definition ai.h:374
city_has_building
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1207
can_city_build_improvement_now
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:838
can_city_build_improvement_later
bool can_city_build_improvement_later(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:855
city.h
city_list_iterate
#define city_list_iterate(citylist, pcity)
Definition city.h:488
city_owner
#define city_owner(_pcity_)
Definition city.h:543
city_list_iterate_end
#define city_list_iterate_end
Definition city.h:490
change_build_target
void change_build_target(struct player *pplayer, struct city *pcity, struct universal *target, enum event_type event)
Definition citytools.c:3061
citytools.h
id
int int id
Definition editgui_g.h:28
effects.h
adv_want
float adv_want
Definition fc_types.h:1206
ADV_WANT_PRINTF
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
O_SHIELD
@ O_SHIELD
Definition fc_types.h:91
Continent_id
signed short Continent_id
Definition fc_types.h:342
wld
struct world wld
Definition game.c:58
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:102
game.h
has_handicap
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
handicaps.h
H_MAP
@ H_MAP
Definition handicaps.h:28
valid_improvement
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
Definition improvement.c:209
can_player_build_improvement_later
bool can_player_build_improvement_later(const struct player *p, const struct impr_type *pimprove)
Definition improvement.c:734
improvement_rule_name
const char * improvement_rule_name(const struct impr_type *pimprove)
Definition improvement.c:250
improvement_index
Impr_type_id improvement_index(const struct impr_type *pimprove)
Definition improvement.c:173
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:341
improvement_has_flag
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Definition improvement.c:381
is_improvement_productive
bool is_improvement_productive(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:615
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:211
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:205
infracache.h
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
unit_move_rate
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
movement.h
pf_map_new
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Definition path_finding.c:3182
pf_map_destroy
void pf_map_destroy(struct pf_map *pfm)
Definition path_finding.c:3206
path_finding.h
pf_map_move_costs_iterate_end
#define pf_map_move_costs_iterate_end
Definition path_finding.h:592
pf_map_move_costs_iterate
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
Definition path_finding.h:582
pft_fill_unit_parameter
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:840
pf_tools.h
player.h
is_ai
#define is_ai(plr)
Definition player.h:234
plrhand.h
rand.h
specialist.h
srv_log.h
CITY_LOG
#define CITY_LOG(loglevel, pcity, msg,...)
Definition srv_log.h:83
adv_choice
Definition advchoice.h:45
adv_choice::type
enum choice_type type
Definition advchoice.h:46
adv_choice::want
adv_want want
Definition advchoice.h:48
adv_choice::value
universals_u value
Definition advchoice.h:47
adv_choice::need_boat
bool need_boat
Definition advchoice.h:49
adv_city
Definition infracache.h:21
adv_city::downtown
int downtown
Definition infracache.h:34
adv_city::building_want
adv_want building_want[B_LAST]
Definition infracache.h:32
adv_data
Definition advdata.h:45
adv_data::threats
struct adv_data::@90 threats
adv_data::stats
struct adv_data::@92 stats
adv_data::cities
int * cities
Definition advdata.h:90
adv_data::continent
bool * continent
Definition advdata.h:59
adv_data::wonder_city
int wonder_city
Definition advdata.h:50
city
Definition city.h:309
city::surplus
int surplus[O_LAST]
Definition city.h:343
city::id
int id
Definition city.h:315
city::production
struct universal production
Definition city.h:382
city::adv
struct adv_city * adv
Definition city.h:435
city::server
struct city::@17::@19 server
civ_map
Definition map_types.h:71
civ_map::server
struct civ_map::@41::@43 server
impr_type
Definition improvement.h:68
pf_map
Definition path_finding.c:78
pf_parameter
Definition path_finding.h:357
pf_parameter::omniscience
bool omniscience
Definition path_finding.h:376
player
Definition player.h:249
player::cities
struct city_list * cities
Definition player.h:281
range
Definition unittype.c:931
unit_type
Definition unittype.h:481
unit
Definition unit.h:138
unit::tile
struct tile * tile
Definition unit.h:140
universal
Definition fc_types.h:756
universal::kind
enum universals_n kind
Definition fc_types.h:758
universal::value
universals_u value
Definition fc_types.h:757
world::map
struct civ_map map
Definition world_object.h:38
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
is_terrain_class_near_tile
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:600
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_continent
#define tile_continent(_tile)
Definition tile.h:91
universals_u::building
const struct impr_type * building
Definition fc_types.h:598
unit_virtual_create
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1613
unit_virtual_destroy
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1709
unit_tile_set
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1278
first_role_unit_for_player
struct unit_type * first_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2370
get_role_unit
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2301
num_role_units
int num_role_units(int role)
Definition unittype.c:2251
best_role_unit_for_player
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2345
utype_can_do_action
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443