Freeciv-3.3: /fast/freeciv/nightly/main/ai/default/daisettler.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
daisettler.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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#include <stdio.h>
19#include <string.h>
20
21/* utility */
22#include "mem.h"
23#include "log.h"
24#include "support.h"
25#include "timing.h"
26
27/* common */
28#include "city.h"
29#include "game.h"
30#include "government.h"
31#include "map.h"
32#include "movement.h"
33#include "packets.h"
34#include "player.h"
35
36/* common/aicore */
37#include "citymap.h"
38#include "pf_tools.h"
39
40/* server */
41#include "citytools.h"
42#include "maphand.h"
43#include "srv_log.h"
44#include "unithand.h"
45#include "unittools.h"
46
47/* server/advisors */
48#include "advdata.h"
49#include "advgoto.h"
50#include "advtools.h"
51#include "autoworkers.h"
52#include "infracache.h"
53
54/* ai */
55#include "handicaps.h"
56
57/* ai/default */
58#include "aiferry.h"
59#include "daicity.h"
60#include "daidata.h"
61#include "dailog.h"
62#include "daiplayer.h"
63#include "daitools.h"
64
65#include "daisettler.h"
66
67
68/* COMMENTS */
69/*
70 This code tries hard to do the right thing, including looking
71 into the future (wrt to government), and also doing this in a
72 modpack friendly manner. However, there are some pieces missing.
73
74 A tighter integration into the city management code would
75 give more optimal city placements, since existing cities could
76 move their workers around to give a new city better placement.
77 Occasionally you will see cities being placed sub-optimally
78 because the best city center tile is taken when another tile
79 could have been worked instead by the city that took it.
80
81 The code is not generic enough. It assumes smallpox too much,
82 and should calculate with a future city of a bigger size.
83
84 We need to stop the build code from running this code all the
85 time and instead try to complete what it has started.
86*/
87
88/* Stop looking too hard for better tiles to found a new city at when
89 * settler finds location with at least RESULT_IS_ENOUGH want
90 * points. See city_desirability() for how base want is computed
91 * before amortizing it.
92 *
93 * This is a big WAG to save a big amount of CPU. */
94#define RESULT_IS_ENOUGH 250
95
96#define FERRY_TECH_WANT 500
97
98#define GROWTH_PRIORITY 15
99
100/* Perfection gives us an idea of how long to search for optimal
101 * solutions, instead of going for quick and dirty solutions that
102 * waste valuable time. Decrease for maps where good city placements
103 * are hard to find. Lower means more perfection. */
104#define PERFECTION 3
105
106/* How much to deemphasise the potential for city growth for city
107 * placements. Decrease this value if large cities are important
108 * or planned. Increase if running strict smallpox. */
109#define GROWTH_POTENTIAL_DEEMPHASIS 8
110
111/* Percentage bonus to city locations near an ocean. */
112#define NAVAL_EMPHASIS 20
113
114/* Modifier for defense bonus that is applied to city location want.
115 * This is % of defense % to increase want by. */
116#define DEFENSE_EMPHASIS 20
117
118 struct tile_data_cache {
119 short food; /* Food output of the tile */
120 short trade; /* Trade output of the tile */
121 short shield; /* Shield output of the tile */
122
123 int sum; /* Weighted sum of the tile output */
124
125 int reserved; /* Reservation for this tile; used by print_citymap() */
126
127 int turn; /* The turn the values were calculated */
128};
129
130
131struct tile_data_cache *tile_data_cache_new(void);
132struct tile_data_cache *
133 tile_data_cache_copy(const struct tile_data_cache *ptdc);
134static void tile_data_cache_destroy(struct tile_data_cache *ptdc);
135
136/* struct tdcache_hash. */
137#define SPECHASH_TAG tile_data_cache
138#define SPECHASH_INT_KEY_TYPE
139#define SPECHASH_IDATA_TYPE struct tile_data_cache *
140#define SPECHASH_IDATA_FREE tile_data_cache_destroy
141#include "spechash.h"
142
143 struct ai_settler {
144 struct tile_data_cache_hash *tdc_hash;
145
146#ifdef FREECIV_DEBUG
147 struct {
148 int hit;
149 int old;
150 int miss;
151 int save;
152 } cache;
153#endif /* FREECIV_DEBUG */
154};
155
156 struct cityresult {
157 struct tile *tile;
158 adv_want total; /* Total value of position */
159 adv_want result; /* Amortized and adjusted total value */
160 int corruption, waste;
161 bool overseas; /* Have to use boat to get there */
162 bool virt_boat; /* Virtual boat was used in search,
163 * so need to build one */
164
165 struct {
166 struct tile_data_cache *tdc; /* Values of city center; link to the data
167 * in tdc_hash. */
168 } city_center;
169
170 struct {
171 struct tile *tile; /* Best other tile */
172 int cindex; /* City-relative index for other tile */
173 struct tile_data_cache *tdc; /* Value of best other tile; link to the
174 * data in tdc_hash. */
175 } best_other;
176
177 adv_want remaining; /* Value of all other tiles */
178
179 /* Save the result for print_citymap(). */
180 struct tile_data_cache_hash *tdc_hash;
181
182 int city_radius_sq; /* Current squared radius of the city */
183};
184
185 enum cb_error_level { CBE_OK, CBE_RECOVERABLE, CBE_FATAL };
186
187static const struct tile_data_cache *tdc_plr_get(struct ai_type *ait,
188 struct player *plr,
189 int tindex);
190static void tdc_plr_set(struct ai_type *ait, struct player *plr, int tindex,
191 const struct tile_data_cache *tdcache);
192
193static struct cityresult *cityresult_new(struct tile *ptile);
194static void cityresult_destroy(struct cityresult *result);
195
196static struct cityresult *cityresult_fill(struct ai_type *ait,
197 struct player *pplayer,
198 struct tile *center);
199static bool food_starvation(const struct cityresult *result);
200static bool shield_starvation(const struct cityresult *result);
201static adv_want result_defense_bonus(struct player *pplayer,
202 const struct cityresult *result);
203static adv_want naval_bonus(const struct cityresult *result);
204static void print_cityresult(struct player *pplayer,
205 const struct cityresult *cr);
206struct cityresult *city_desirability(struct ai_type *ait,
207 struct player *pplayer,
208 struct unit *punit, struct tile *ptile);
209static struct cityresult *settler_map_iterate(struct ai_type *ait,
210 struct pf_parameter *parameter,
211 struct unit *punit,
212 int boat_cost);
213static struct cityresult *find_best_city_placement(struct ai_type *ait,
214 struct unit *punit,
215 bool look_for_boat,
216 bool use_virt_boat);
217static enum cb_error_level dai_do_build_city(struct ai_type *ait,
218 struct player *pplayer,
219 struct unit *punit);
220
221/*************************************************************************/
224 static struct cityresult *cityresult_new(struct tile *ptile)
225{
226 struct cityresult *result;
227
228 fc_assert_ret_val(ptile != NULL, NULL);
229
230 result = fc_calloc(1, sizeof(*result));
231 result->tile = ptile;
232 result->total = 0;
233 result->result = -666;
234 result->corruption = 0;
235 result->waste = 0;
236 result->overseas = FALSE;
237 result->virt_boat = FALSE;
238
239 /* City centre */
240 result->city_center.tdc = NULL;
241
242 /* First worked tile */
243 result->best_other.tile = NULL;
244 result->best_other.tdc = NULL;
245 result->best_other.cindex = 0;
246
247 result->remaining = 0;
248 result->tdc_hash = tile_data_cache_hash_new();
249 result->city_radius_sq = game.info.init_city_radius_sq;
250
251 return result;
252}
253
254/*************************************************************************/
257 static void cityresult_destroy(struct cityresult *result)
258{
259 if (result != NULL) {
260 if (result->tdc_hash != NULL) {
261 tile_data_cache_hash_destroy(result->tdc_hash);
262 }
263 free(result);
264 }
265}
266
267/*************************************************************************/
275 static struct cityresult *cityresult_fill(struct ai_type *ait,
276 struct player *pplayer,
277 struct tile *center)
278{
279 struct city *pcity = tile_city(center);
280 struct government *curr_govt = government_of_player(pplayer);
281 struct player *saved_owner = NULL;
282 struct tile *saved_claimer = NULL;
283 bool virtual_city = FALSE;
284 bool handicap = has_handicap(pplayer, H_MAP);
285 struct adv_data *adv = adv_data_get(pplayer, NULL);
286 struct cityresult *result;
287 const struct civ_map *nmap = &(wld.map);
288
289 fc_assert_ret_val(adv != NULL, NULL);
290 fc_assert_ret_val(center != NULL, NULL);
291
292 pplayer->government = adv->goal.govt.gov;
293
294 /* Create a city result and set default values. */
295 result = cityresult_new(center);
296
297 if (pcity == NULL) {
298 pcity = create_city_virtual(pplayer, result->tile, "Virtuaville");
299 saved_owner = tile_owner(result->tile);
300 saved_claimer = tile_claimer(result->tile);
301 tile_set_owner(result->tile, pplayer, result->tile); /* Temporarily */
302 city_choose_build_default(pcity); /* ?? */
303 virtual_city = TRUE;
304 }
305
306 result->city_radius_sq = city_map_radius_sq_get(pcity);
307
308 city_tile_iterate_index(nmap, result->city_radius_sq, result->tile, ptile,
309 cindex) {
310 int tindex = tile_index(ptile);
311 int reserved = citymap_read(ptile);
312 bool city_center = (result->tile == ptile); /* is_city_center() */
313 struct tile_data_cache *ptdc;
314
315 if (reserved < 0
316 || (handicap && !map_is_known(ptile, pplayer))
317 || tile_worked(ptile) != NULL) {
318 /* Tile is reserved or we can't see it */
319 ptdc = tile_data_cache_new();
320 ptdc->shield = 0;
321 ptdc->trade = 0;
322 ptdc->food = 0;
323 ptdc->sum = -1;
324 ptdc->reserved = reserved;
325 /* ptdc->turn was set by tile_data_cache_new(). */
326 } else {
327 const struct tile_data_cache *ptdc_hit = tdc_plr_get(ait, pplayer, tindex);
328
329 if (!ptdc_hit || city_center) {
330 /* We cannot read city center from cache */
331 ptdc = tile_data_cache_new();
332
333 /* Food */
334 ptdc->food = city_tile_output(pcity, ptile, FALSE, O_FOOD);
335 /* Shields */
336 ptdc->shield = city_tile_output(pcity, ptile, FALSE, O_SHIELD);
337 /* Trade */
338 ptdc->trade = city_tile_output(pcity, ptile, FALSE, O_TRADE);
339 /* Weighted sum */
340 ptdc->sum = ptdc->food * adv->food_priority
341 + ptdc->trade * adv->science_priority
342 + ptdc->shield * adv->shield_priority;
343 /* Balance perfection */
344 ptdc->sum *= PERFECTION / 2;
345 if (ptdc->food >= 2) {
346 ptdc->sum *= 2; /* we need this to grow */
347 }
348
349 if (!city_center && virtual_city) {
350 /* Real cities and any city center will give us possibly
351 * skewed results */
352 tdc_plr_set(ait, pplayer, tindex, tile_data_cache_copy(ptdc));
353 }
354 } else {
355 ptdc = tile_data_cache_copy(ptdc_hit);
356 }
357 }
358
359 /* Save reservation status for debugging. */
360 ptdc->reserved = reserved;
361
362 /* Avoid crowdedness, except for city center. */
363 if (ptdc->sum > 0) {
364 ptdc->sum -= MIN(reserved * GROWTH_PRIORITY, ptdc->sum - 1);
365 }
366
367 /* Calculate city center and best other than city center */
368 if (city_center) {
369 /* Set city center. */
370 result->city_center.tdc = ptdc;
371 } else if (!result->best_other.tdc) {
372 /* Set best other tile. */
373 result->best_other.tdc = ptdc;
374 result->best_other.tile = ptile;
375 result->best_other.cindex = cindex;
376 } else if (ptdc->sum > result->best_other.tdc->sum) {
377 /* First add other other to remaining, unless it's unavailable (value < 0) tile. */
378 if (result->best_other.tdc->sum > 0) {
379 result->remaining += result->best_other.tdc->sum
380 / GROWTH_POTENTIAL_DEEMPHASIS;
381 }
382 /* Then make new best other */
383 result->best_other.tdc = ptdc;
384 result->best_other.tile = ptile;
385 result->best_other.cindex = cindex;
386 } else {
387 /* Save total remaining calculation, divided by crowdedness
388 * of the area and the emphasis placed on space for growth.
389 * Do not add unavailable (value < 0) tiles. */
390 if (ptdc->sum > 0) {
391 result->remaining += ptdc->sum / GROWTH_POTENTIAL_DEEMPHASIS;
392 }
393 }
394
395 tile_data_cache_hash_replace(result->tdc_hash, cindex, ptdc);
396 } city_tile_iterate_index_end;
397
398 /* We need a city center. */
399 if (result->city_center.tdc == NULL) {
400 fc_assert(result->city_center.tdc != NULL);
401
402 return NULL;
403 }
404
405 if (virtual_city) {
406 /* Baseline is a size one city (city center + best extra tile). */
407 result->total = result->city_center.tdc->sum
408 + (result->best_other.tdc != NULL
409 ? result->best_other.tdc->sum : 0);
410 } else if (result->best_other.tdc != NULL) {
411 /* Baseline is best extra tile only. This is why making new cities
412 * is so darn good. */
413 result->total = result->best_other.tdc->sum;
414 } else {
415 /* There is no available tile in this city. All is worked. */
416 result->total = 0;
417 return result;
418 }
419
420 /* Now we have a valid city center as well as best other tile. */
421
422 if (virtual_city) {
423 /* Corruption and waste of a size one city deducted. Notice that we
424 * don't do this if 'fulltradesize' is changed, since then we'd
425 * never make cities. */
426 int shield = result->city_center.tdc->shield
427 + result->best_other.tdc->shield;
428 result->waste = adv->shield_priority
429 * city_waste(pcity, O_SHIELD, shield, NULL);
430
431 if (game.info.fulltradesize == 1) {
432 int trade = result->city_center.tdc->trade
433 + result->best_other.tdc->trade;
434 result->corruption = adv->science_priority
435 * city_waste(pcity, O_TRADE, trade, NULL);
436 } else {
437 result->corruption = 0;
438 }
439 } else {
440 /* Deduct difference in corruption and waste for real cities. Note that it
441 * is possible (with notradesize) that we _gain_ value here. */
442 city_size_add(pcity, 1);
443 result->corruption = adv->science_priority
444 * (city_waste(pcity, O_TRADE, result->best_other.tdc->trade, NULL)
445 - pcity->waste[O_TRADE]);
446 result->waste = adv->shield_priority
447 * (city_waste(pcity, O_SHIELD, result->best_other.tdc->shield, NULL)
448 - pcity->waste[O_SHIELD]);
449 city_size_add(pcity, -1);
450 }
451 result->total -= result->corruption;
452 result->total -= result->waste;
453 result->total = MAX(0, result->total);
454
455 pplayer->government = curr_govt;
456 if (virtual_city) {
457 destroy_city_virtual(pcity);
458 tile_set_owner(result->tile, saved_owner, saved_claimer);
459 }
460
461 fc_assert_ret_val(result->city_center.tdc->sum >= 0, NULL);
462 fc_assert_ret_val(result->remaining >= 0, NULL);
463
464 return result;
465}
466
467/*************************************************************************/
470 struct tile_data_cache *tile_data_cache_new(void)
471{
472 struct tile_data_cache *ptdc_copy = fc_calloc(1, sizeof(*ptdc_copy));
473
474 /* Set the turn the tile data cache was created. */
475 ptdc_copy->turn = game.info.turn;
476
477 return ptdc_copy;
478}
479
480/*************************************************************************/
483struct tile_data_cache *
484 tile_data_cache_copy(const struct tile_data_cache *ptdc)
485{
486 struct tile_data_cache *ptdc_copy = tile_data_cache_new();
487
488 fc_assert_ret_val(ptdc, NULL);
489
490 ptdc_copy->shield = ptdc->shield;
491 ptdc_copy->trade = ptdc->trade;
492 ptdc_copy->food = ptdc->food;
493
494 ptdc_copy->sum = ptdc->sum;
495 ptdc_copy->reserved = ptdc->reserved;
496 ptdc_copy->turn = ptdc->turn;
497
498 return ptdc_copy;
499}
500
501/*************************************************************************/
504 static void tile_data_cache_destroy(struct tile_data_cache *ptdc)
505{
506 if (ptdc != NULL) {
507 free(ptdc);
508 }
509}
510
511/*************************************************************************/
514 static const struct tile_data_cache *tdc_plr_get(struct ai_type *ait,
515 struct player *plr,
516 int tindex)
517{
518 struct ai_plr *ai = dai_plr_data_get(ait, plr, NULL);
519
520 fc_assert_ret_val(ai != NULL, NULL);
521 fc_assert_ret_val(ai->settler != NULL, NULL);
522 fc_assert_ret_val(ai->settler->tdc_hash != NULL, NULL);
523
524 struct tile_data_cache *ptdc;
525
526 tile_data_cache_hash_lookup(ai->settler->tdc_hash, tindex, &ptdc);
527
528 if (!ptdc) {
529#ifdef FREECIV_DEBUG
530 ai->settler->cache.miss++;
531#endif /* FREECIV_DEBUG */
532 return NULL;
533 } else if (ptdc->turn != game.info.turn) {
534#ifdef FREECIV_DEBUG
535 ai->settler->cache.old++;
536#endif /* FREECIV_DEBUG */
537 return NULL;
538 } else {
539#ifdef FREECIV_DEBUG
540 ai->settler->cache.hit++;
541#endif /* FREECIV_DEBUG */
542 return ptdc;
543 }
544}
545
546/*************************************************************************/
549 static void tdc_plr_set(struct ai_type *ait, struct player *plr, int tindex,
550 const struct tile_data_cache *ptdc)
551{
552 struct ai_plr *ai = dai_plr_data_get(ait, plr, NULL);
553
554 fc_assert_ret(ai != NULL);
555 fc_assert_ret(ai->settler != NULL);
556 fc_assert_ret(ai->settler->tdc_hash != NULL);
557 fc_assert_ret(ptdc != NULL);
558
559#ifdef FREECIV_DEBUG
560 ai->settler->cache.save++;
561#endif /* FREECIV_DEBUG */
562
563 tile_data_cache_hash_replace(ai->settler->tdc_hash, tindex, ptdc);
564}
565
566/*************************************************************************/
569 static bool food_starvation(const struct cityresult *result)
570{
571 /* Avoid starvation: We must have enough food to grow.
572 * Note: this does not handle the case of a newly founded city breaking
573 * even but being immediately able to build an improvement increasing its
574 * yield (such as supermarkets and harbors in the classic ruleset).
575 * /MSS */
576 return (result->city_center.tdc->food
577 + (result->best_other.tdc ? result->best_other.tdc->food
578 : 0) <= game.info.food_cost);
579}
580
581/*************************************************************************/
584 static bool shield_starvation(const struct cityresult *result)
585{
586 /* Avoid resource starvation. */
587 return (result->city_center.tdc->shield
588 + (result->best_other.tdc ? result->best_other.tdc->shield
589 : 0) == 0);
590}
591
592/*************************************************************************/
596 static adv_want result_defense_bonus(struct player *pplayer,
597 const struct cityresult *result)
598{
599 /* Defense modification (as tie breaker mostly) */
600 int defense_bonus
601 = 10 + tile_terrain(result->tile)->defense_bonus / 10;
602 int extra_bonus = 0;
603 struct tile *vtile = tile_virtual_new(result->tile);
604 struct city *vcity = create_city_virtual(pplayer, vtile, "");
605
606 tile_set_worked(vtile, vcity); /* Link tile_city(vtile) to vcity. */
607 upgrade_city_extras(vcity, NULL); /* Give city free extras. */
608 extra_type_iterate(pextra) {
609 if (tile_has_extra(vtile, pextra)) {
610 /* TODO: Do not use full bonus of those road types
611 * that are not native to all important units. */
612 extra_bonus += pextra->defense_bonus;
613 }
614 } extra_type_iterate_end;
615 tile_virtual_destroy(vtile);
616
617 defense_bonus += (defense_bonus * extra_bonus) / 100;
618
619 return 100 / (result->total + 1) * (100 / defense_bonus * DEFENSE_EMPHASIS);
620}
621
622/*************************************************************************/
625 static adv_want naval_bonus(const struct cityresult *result)
626{
627 bool ocean_adjacent = is_terrain_class_near_tile(&(wld.map),
628 result->tile, TC_OCEAN);
629
630 /* Adjust for ocean adjacency, which is nice */
631 if (ocean_adjacent) {
632 return (result->total * NAVAL_EMPHASIS) / 100;
633 } else {
634 return 0;
635 }
636}
637
638/*************************************************************************/
641 static void print_cityresult(struct player *pplayer,
642 const struct cityresult *cr)
643{
644 int *city_map_reserved, *city_map_food, *city_map_shield, *city_map_trade;
645 int tiles = city_map_tiles(cr->city_radius_sq);
646 struct tile_data_cache *ptdc;
647
648 fc_assert_ret(cr->tdc_hash != NULL);
649 fc_assert_ret(tiles > 0);
650
651 city_map_reserved = fc_calloc(tiles, sizeof(*city_map_reserved));
652 city_map_food = fc_calloc(tiles, sizeof(*city_map_food));
653 city_map_shield = fc_calloc(tiles, sizeof(*city_map_shield));
654 city_map_trade = fc_calloc(tiles, sizeof(*city_map_trade));
655
656 city_map_iterate(cr->city_radius_sq, cindex, x, y) {
657 tile_data_cache_hash_lookup(cr->tdc_hash, cindex, &ptdc);
658 fc_assert_ret(ptdc);
659 city_map_reserved[cindex] = ptdc->reserved;
660 city_map_food[cindex] = ptdc->reserved;
661 city_map_shield[cindex] = ptdc->reserved;
662 city_map_trade[cindex] = ptdc->reserved;
663 } city_map_iterate_end;
664
665 /* Print reservations */
666 log_test("cityresult for (x, y, radius_sq) = (%d, %d, %d) - Reservations:",
667 TILE_XY(cr->tile), cr->city_radius_sq);
668 citylog_map_data(LOG_TEST, cr->city_radius_sq, city_map_reserved);
669
670 /* Print food */
671 log_test("cityresult for (x, y, radius_sq) = (%d, %d, %d) - Food:",
672 TILE_XY(cr->tile), cr->city_radius_sq);
673 citylog_map_data(LOG_TEST, cr->city_radius_sq, city_map_food);
674
675 /* Print shield */
676 log_test("cityresult for (x, y, radius_sq) = (%d, %d, %d) - Shield:",
677 TILE_XY(cr->tile), cr->city_radius_sq);
678 citylog_map_data(LOG_TEST, cr->city_radius_sq, city_map_shield);
679
680 /* Print trade */
681 log_test("cityresult for (x, y, radius_sq) = (%d, %d, %d) - Trade:",
682 TILE_XY(cr->tile), cr->city_radius_sq);
683 citylog_map_data(LOG_TEST, cr->city_radius_sq, city_map_trade);
684
685 free(city_map_reserved);
686 free(city_map_food);
687 free(city_map_shield);
688 free(city_map_trade);
689
690 log_test("city center (%d, %d) %d + best other (abs: %d, %d)"
691 " (cindex: %d) %d", TILE_XY(cr->tile),
692 cr->city_center.tdc->sum, TILE_XY(cr->best_other.tile),
693 cr->best_other.cindex, cr->best_other.tdc->sum);
694 log_test("- corr %d - waste %d + remaining " ADV_WANT_PRINTF
695 " + defense bonus " ADV_WANT_PRINTF " + naval bonus " ADV_WANT_PRINTF,
696 cr->corruption, cr->waste, cr->remaining,
697 result_defense_bonus(pplayer, cr), naval_bonus(cr));
698 log_test("= " ADV_WANT_PRINTF " (" ADV_WANT_PRINTF ")", cr->total, cr->result);
699
700 if (food_starvation(cr)) {
701 log_test(" ** FOOD STARVATION **");
702 }
703 if (shield_starvation(cr)) {
704 log_test(" ** RESOURCE STARVATION **");
705 }
706}
707
708/*************************************************************************/
713 struct cityresult *city_desirability(struct ai_type *ait, struct player *pplayer,
714 struct unit *punit, struct tile *ptile)
715{
716 struct city *pcity = tile_city(ptile);
717 struct cityresult *cr = NULL;
718 const struct civ_map *nmap = &(wld.map);
719
720 fc_assert_ret_val(punit, NULL);
721 fc_assert_ret_val(pplayer, NULL);
722
723 if (!city_can_be_built_here(nmap, ptile, punit, FALSE)
724 || (has_handicap(pplayer, H_MAP)
725 && !map_is_known(ptile, pplayer))) {
726 return NULL;
727 }
728
729 /* Check if another settler has taken a spot within mindist */
730 square_iterate(&(wld.map), ptile, game.info.citymindist-1, tile1) {
731 if (citymap_is_reserved(tile1)) {
732 return NULL;
733 }
734 } square_iterate_end;
735
736 if (adv_danger_at(punit, ptile)) {
737 return NULL;
738 }
739
740 if (pcity && (city_size_get(pcity) + unit_pop_value(punit)
741 > game.info.add_to_size_limit)) {
742 /* Can't exceed population limit. */
743 return NULL;
744 }
745
746 if (!pcity && citymap_is_reserved(ptile)) {
747 return NULL; /* reserved, go away */
748 }
749
750 /* If (x, y) is an existing city, consider immigration */
751 if (pcity && city_owner(pcity) == pplayer) {
752 return NULL;
753 }
754
755 cr = cityresult_fill(ait, pplayer, ptile); /* Burn CPU, burn! */
756 if (!cr) {
757 /* Failed to find a good spot */
758 return NULL;
759 }
760
761 /*** Alright: Now consider building a new city ***/
762
763 if (food_starvation(cr) || shield_starvation(cr)) {
764 cityresult_destroy(cr);
765 return NULL;
766 }
767
768 cr->total += result_defense_bonus(pplayer, cr);
769 cr->total += naval_bonus(cr);
770
771 /* Add remaining points, which is our potential */
772 cr->total += cr->remaining;
773
774 fc_assert_ret_val(cr->total >= 0, NULL); /* Does not free cr! */
775
776 return cr;
777}
778
779/*************************************************************************/
790 static struct cityresult *settler_map_iterate(struct ai_type *ait,
791 struct pf_parameter *parameter,
792 struct unit *punit,
793 int boat_cost)
794{
795 struct cityresult *cr = NULL, *best = NULL;
796 int best_turn = 0; /* Which turn we found the best fit */
797 struct player *pplayer = unit_owner(punit);
798 struct pf_map *pfm;
799 struct unit_class *pclass = unit_class_get(punit);
800 Continent_id curcont = tile_continent(unit_tile(punit));
801 int cost = unit_build_shield_cost_base(punit);
802
803 pfm = pf_map_new(parameter);
804 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
805 int turns;
806
807 if (boat_cost == 0 && pclass->adv.sea_move == MOVE_NONE
808 && tile_continent(ptile) != curcont) {
809 /* We have an accidential land bridge. Ignore it. It will in all
810 * likelihood go away next turn, or even in a few nanoseconds. */
811 continue;
812 }
813 if (BORDERS_DISABLED != game.info.borders) {
814 struct player *powner = tile_owner(ptile);
815
816 if (NULL != powner
817 && powner != pplayer
818 && pplayers_in_peace(powner, pplayer)) {
819 /* Land theft does not make for good neighbors. */
820 continue;
821 }
822 }
823
824 /* Calculate worth */
825 cr = city_desirability(ait, pplayer, punit, ptile);
826
827 /* Check if actually found something */
828 if (cr == NULL) {
829 continue;
830 }
831
832 /* This algorithm punishes long treks */
833 turns = move_cost / parameter->move_rate;
834 cr->result = amortize(cr->total, PERFECTION * turns);
835
836 /* Reduce want by settler cost. Easier than amortize, but still
837 * weeds out very small wants. ie we create a threshold here. */
838 /* We also penalise here for using a boat (either virtual or real)
839 * it's crude but what isn't?
840 * Settler gets used, boat can make multiple trips. */
841 cr->result -= cost + boat_cost / 3;
842
843 /* Find best spot */
844 if ((!best && cr->result > 0)
845 || (best && cr->result > best->result)) {
846 /* Destroy the old 'best' value. */
847 cityresult_destroy(best);
848 /* Save the new 'best' value. */
849 best = cr;
850 cr = NULL;
851 best_turn = turns;
852
853 log_debug("settler map search (search): (%d, %d) " ADV_WANT_PRINTF,
854 TILE_XY(best->tile), best->result);
855 } else {
856 /* Destroy the unused result. */
857 cityresult_destroy(cr);
858 cr = NULL;
859 }
860
861 /* Can we terminate early? We have a 'good enough' spot, and
862 * we don't block the establishment of a better city just one
863 * further step away. */
864 if (best && best->result > RESULT_IS_ENOUGH
865 && turns > parameter->move_rate /* sic -- yeah what an explanation! */
866 && best_turn < turns /*+ game.info.min_dist_bw_cities*/) {
867 break;
868 }
869 } pf_map_move_costs_iterate_end;
870
871 pf_map_destroy(pfm);
872
873 if (best) {
874 log_debug("settler map search (final): (%d, %d) " ADV_WANT_PRINTF,
875 TILE_XY(best->tile), best->result);
876 } else {
877 log_debug("settler map search (final): no result");
878 }
879
880 return best;
881}
882
883/*************************************************************************/
896 static struct cityresult *find_best_city_placement(struct ai_type *ait,
897 struct unit *punit,
898 bool look_for_boat,
899 bool use_virt_boat)
900{
901 struct pf_parameter parameter;
902 struct player *pplayer = unit_owner(punit);
903 struct unit *ferry = NULL;
904 struct cityresult *cr1 = NULL, *cr2 = NULL;
905 const struct civ_map *nmap = &(wld.map);
906
907 fc_assert_ret_val(is_ai(pplayer), NULL);
908 /* Only virtual units may use virtual boats: */
909 fc_assert_ret_val(0 == punit->id || !use_virt_boat, NULL);
910
911 /* Phase 1: Consider building cities on our continent */
912
913 pft_fill_unit_parameter(&parameter, nmap, punit);
914 parameter.omniscience = !has_handicap(pplayer, H_MAP);
915 cr1 = settler_map_iterate(ait, &parameter, punit, 0);
916
917 if (cr1 && cr1->result > RESULT_IS_ENOUGH) {
918 /* skip further searches */
919 return cr1;
920 }
921
922 /* Phase 2: Consider travelling to another continent */
923
924 if (look_for_boat) {
925 int ferry_id = aiferry_find_boat(ait, punit, 1, NULL);
926
927 ferry = game_unit_by_number(ferry_id);
928 }
929
930 if (ferry || (use_virt_boat
931 && is_terrain_class_near_tile(&(wld.map),
932 unit_tile(punit), TC_OCEAN)
933 && tile_city(unit_tile(punit)))) {
934 if (!ferry) {
935 /* No boat? Get a virtual one! */
936 struct unit_type *boattype
937 = best_role_unit_for_player(pplayer, L_FERRYBOAT);
938
939 if (boattype == NULL) {
940 /* Sea travel not possible yet. Bump tech want for ferries. */
941 boattype = get_role_unit(L_FERRYBOAT, 0);
942
943 if (NULL != boattype) {
944 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
945
946 unit_tech_reqs_iterate(boattype, padv) {
947 plr_data->tech_want[advance_index(padv)]
948 += FERRY_TECH_WANT;
949 TECH_LOG(ait, LOG_DEBUG, pplayer, padv,
950 "+ %d for %s to ferry settler",
951 FERRY_TECH_WANT,
952 utype_rule_name(boattype));
953 } unit_tech_reqs_iterate_end;
954 }
955
956 /* Return the result from the search on our current continent */
957 return cr1;
958 }
959 ferry = unit_virtual_create(pplayer, NULL, boattype, 0);
960 unit_tile_set(ferry, unit_tile(punit));
961 }
962
963 fc_assert(dai_is_ferry(ferry, ait));
964 pft_fill_unit_overlap_param(&parameter, nmap, ferry);
965 parameter.omniscience = !has_handicap(pplayer, H_MAP);
966 parameter.get_TB = no_fights_or_unknown;
967
968 /* FIXME: Maybe penalty for using an existing boat is too high?
969 * We shouldn't make the penalty for building a new boat too high though.
970 * Building a new boat is like a war against a weaker enemy --
971 * good for the economy. (c) Bush family */
972 cr2 = settler_map_iterate(ait, &parameter, punit,
973 unit_build_shield_cost_base(ferry));
974 if (cr2) {
975 cr2->overseas = TRUE;
976 cr2->virt_boat = (ferry->id == 0);
977 }
978
979 if (ferry->id == 0) {
980 unit_virtual_destroy(ferry);
981 }
982
983 /* If we use a virtual boat, we must have permission and be emigrating: */
984 /* FIXME: These assert do not free cr2! */
985 fc_assert_ret_val(!cr2 || (!cr2->virt_boat || use_virt_boat), NULL);
986 fc_assert_ret_val(!cr2 || (!cr2->virt_boat || cr2->overseas), NULL);
987 }
988
989 if (!cr1) {
990 /* No want for a new city on our current continent; return the result for
991 * traveling by boat. */
992 return cr2;
993 } else if (!cr2) {
994 /* No want for an overseas city; return the result for a city on our
995 * current continent. */
996 return cr1;
997 }
998
999 /* We want an overseas city and a city on the current continent - select the
1000 * best! */
1001 if (cr1->result > cr2->result) {
1002 cityresult_destroy(cr2);
1003 return cr1;
1004 } else {
1005 cityresult_destroy(cr1);
1006 return cr2;
1007 }
1008}
1009
1010/*************************************************************************/
1013 void dai_auto_settler_init(struct ai_plr *ai)
1014{
1015 fc_assert_ret(ai != NULL);
1016 fc_assert_ret(ai->settler == NULL);
1017
1018 ai->settler = fc_calloc(1, sizeof(*ai->settler));
1019 ai->settler->tdc_hash = tile_data_cache_hash_new();
1020
1021#ifdef FREECIV_DEBUG
1022 ai->settler->cache.hit = 0;
1023 ai->settler->cache.old = 0;
1024 ai->settler->cache.miss = 0;
1025 ai->settler->cache.save = 0;
1026#endif /* FREECIV_DEBUG */
1027}
1028
1029/*************************************************************************/
1032 void dai_auto_settler_run(struct ai_type *ait, const struct civ_map *nmap,
1033 struct player *pplayer,
1034 struct unit *punit, struct workermap *state)
1035{
1036 adv_want best_impr = 0; /* Value of best terrain improvement we can do */
1037 enum unit_activity best_act;
1038 struct extra_type *best_target;
1039 struct tile *best_tile = NULL;
1040 struct pf_path *path = NULL;
1041 struct city *pcity = NULL;
1042
1043 /* Time it will take worker to complete its given task */
1044 int completion_time = 0;
1045
1046 CHECK_UNIT(punit);
1047
1048 /*** If we are on a city mission: Go where we should ***/
1049
1050 BUILD_CITY:
1051
1052 if (def_ai_unit_data(punit, ait)->task == AIUNIT_BUILD_CITY) {
1053 struct tile *ptile = punit->goto_tile;
1054 int sanity = punit->id;
1055
1056 /* Check that the mission is still possible. If the tile has become
1057 * unavailable, call it off. */
1058 if (!city_can_be_built_here(nmap, ptile, punit, FALSE)) {
1059 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
1060 set_unit_activity(punit, ACTIVITY_IDLE, ACTION_NONE);
1061 send_unit_info(NULL, punit);
1062
1063 return; /* Avoid recursion at all cost */
1064 } else {
1065 /* Go there */
1066 if ((!dai_gothere(ait, pplayer, punit, ptile)
1067 && NULL == game_unit_by_number(sanity))
1068 || punit->moves_left <= 0) {
1069 return;
1070 }
1071 if (same_pos(unit_tile(punit), ptile)) {
1072 enum cb_error_level elevel = dai_do_build_city(ait, pplayer, punit);
1073
1074 if (elevel != CBE_OK) {
1075 UNIT_LOG(LOG_DEBUG, punit, "could not make city on %s",
1076 tile_get_info_text(unit_tile(punit), TRUE, 0));
1077 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
1078
1079 if (elevel == CBE_RECOVERABLE) {
1080 /* Only known way to end in here is that hut turned in to a city
1081 * when settler entered tile. So this is not going to lead in any
1082 * serious recursion. */
1083 dai_auto_settler_run(ait, nmap, pplayer, punit, state);
1084 }
1085
1086 return;
1087 } else {
1088 return; /* We came, we saw, we built... */
1089 }
1090 } else {
1091 UNIT_LOG(LOG_DEBUG, punit, "could not go to target");
1092 /* dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); */
1093 return;
1094 }
1095 }
1096 }
1097
1098 /*** Try find some work ***/
1099
1100 if (unit_has_type_flag(punit, UTYF_WORKERS)) {
1101 struct worker_task *best_task;
1102
1103 TIMING_LOG(AIT_WORKERS, TIMER_START);
1104
1105 /* Have nearby cities requests? */
1106 pcity = worker_evaluate_city_requests(punit, &best_task, &path, state);
1107
1108 if (pcity != NULL) {
1109 if (path != NULL) {
1110 completion_time = pf_path_last_position(path)->turn;
1111 best_impr = 1;
1112 best_act = best_task->act;
1113 best_target = best_task->tgt;
1114 best_tile = best_task->ptile;
1115 } else {
1116 pcity = NULL;
1117 }
1118 }
1119
1120 if (pcity == NULL) {
1121 best_impr = worker_evaluate_improvements(nmap, punit,
1122 &best_act, &best_target,
1123 &best_tile, &path, state);
1124 if (path != NULL) {
1125 completion_time = pf_path_last_position(path)->turn;
1126 }
1127 }
1128 UNIT_LOG(LOG_DEBUG, punit, "impr want " ADV_WANT_PRINTF, best_impr);
1129 TIMING_LOG(AIT_WORKERS, TIMER_STOP);
1130 }
1131
1132 if (unit_is_cityfounder(punit)) {
1133 struct cityresult *result;
1134
1135 /* May use a boat: */
1136 TIMING_LOG(AIT_SETTLERS, TIMER_START);
1137 result = find_best_city_placement(ait, punit, TRUE, FALSE);
1138 TIMING_LOG(AIT_SETTLERS, TIMER_STOP);
1139 if (result && result->result > best_impr) {
1140 UNIT_LOG(LOG_DEBUG, punit, "city want " ADV_WANT_PRINTF, result->result);
1141 if (tile_city(result->tile)) {
1142 UNIT_LOG(LOG_DEBUG, punit, "immigrates to %s (%d, %d)",
1143 city_name_get(tile_city(result->tile)),
1144 TILE_XY(result->tile));
1145 } else {
1146 UNIT_LOG(LOG_DEBUG, punit, "makes city at (%d, %d)",
1147 TILE_XY(result->tile));
1148 if (punit->server.debug) {
1149 print_cityresult(pplayer, result);
1150 }
1151 }
1152 /* Go make a city! */
1153 adv_unit_new_task(punit, AUT_BUILD_CITY, result->tile);
1154 if (result->best_other.tile && result->best_other.tdc->sum >= 0) {
1155 /* Reserve best other tile (if there is one). It is the tile where the
1156 * first citizen of the city is working. */
1157 citymap_reserve_tile(result->best_other.tile, punit->id);
1158 }
1159 punit->goto_tile = result->tile; /* TMP */
1160
1161 cityresult_destroy(result);
1162
1163 /*** Go back to and found a city ***/
1164 pf_path_destroy(path);
1165 path = NULL;
1166 goto BUILD_CITY;
1167 } else if (best_impr > 0) {
1168 UNIT_LOG(LOG_DEBUG, punit, "improves terrain instead of founding");
1169 /* Terrain improvements follows the old model, and is recalculated
1170 * each turn. */
1171 if (result) {
1172 /* We had a city result, just worse than best impr */
1173 cityresult_destroy(result);
1174 }
1175 adv_unit_new_task(punit, AUT_AUTO_WORKER, best_tile);
1176 } else {
1177 UNIT_LOG(LOG_DEBUG, punit, "cannot find work");
1178 fc_assert(result == NULL);
1179 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
1180 goto CLEANUP;
1181 }
1182 } else {
1183 /* We are a worker or engineer */
1184 adv_unit_new_task(punit, AUT_AUTO_WORKER, best_tile);
1185 }
1186
1187 if (best_tile != NULL
1188 && auto_worker_setup_work(nmap, pplayer, punit, state, 0, path,
1189 best_tile, best_act, &best_target,
1190 completion_time)) {
1191 if (pcity != NULL) {
1192 clear_worker_tasks(pcity);
1193 }
1194 }
1195
1196 CLEANUP:
1197
1198 if (NULL != path) {
1199 pf_path_destroy(path);
1200 }
1201}
1202
1203/*************************************************************************/
1206 void dai_auto_settler_cont(struct ai_type *ait, const struct civ_map *nmap,
1207 struct player *pplayer,
1208 struct unit *punit, struct workermap *state)
1209{
1210 if (!adv_worker_safe_tile(nmap, pplayer, punit,
1211 unit_tile(punit))) {
1212 unit_activity_handling(punit, ACTIVITY_IDLE, ACTION_NONE);
1213 }
1214}
1215
1216/*************************************************************************/
1219 void dai_auto_settler_reset(struct ai_type *ait, struct player *pplayer)
1220{
1221 bool caller_closes;
1222 struct ai_plr *ai = dai_plr_data_get(ait, pplayer, &caller_closes);
1223
1224 fc_assert_ret(ai != NULL);
1225 fc_assert_ret(ai->settler != NULL);
1226 fc_assert_ret(ai->settler->tdc_hash != NULL);
1227
1228#ifdef FREECIV_DEBUG
1229 log_debug("[aisettler cache for %s] save: %d, miss: %d, old: %d, hit: %d",
1230 player_name(pplayer), ai->settler->cache.save,
1231 ai->settler->cache.miss, ai->settler->cache.old,
1232 ai->settler->cache.hit);
1233
1234 ai->settler->cache.hit = 0;
1235 ai->settler->cache.old = 0;
1236 ai->settler->cache.miss = 0;
1237 ai->settler->cache.save = 0;
1238#endif /* FREECIV_DEBUG */
1239
1240 tile_data_cache_hash_clear(ai->settler->tdc_hash);
1241
1242 if (caller_closes) {
1243 dai_data_phase_finished(ait, pplayer);
1244 }
1245}
1246
1247/*************************************************************************/
1250 void dai_auto_settler_free(struct ai_plr *ai)
1251{
1252 fc_assert_ret(ai != NULL);
1253
1254 if (ai->settler) {
1255 if (ai->settler->tdc_hash) {
1256 tile_data_cache_hash_destroy(ai->settler->tdc_hash);
1257 }
1258 free(ai->settler);
1259 }
1260 ai->settler = NULL;
1261}
1262
1263/*************************************************************************/
1266 static enum cb_error_level dai_do_build_city(struct ai_type *ait,
1267 struct player *pplayer,
1268 struct unit *punit)
1269{
1270 struct tile *ptile = unit_tile(punit);
1271 struct city *pcity;
1272
1273 fc_assert_ret_val(pplayer == unit_owner(punit), FALSE);
1274 unit_activity_handling(punit, ACTIVITY_IDLE, ACTION_NONE);
1275
1276 /* Free city reservations */
1277 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
1278
1279 pcity = tile_city(ptile);
1280 if (pcity) {
1281 /* This can happen for instance when there was hut at this tile
1282 * and it turned in to a city when settler entered tile. */
1283 log_debug("%s: There is already a city at (%d, %d)!",
1284 player_name(pplayer), TILE_XY(ptile));
1285 return CBE_RECOVERABLE;
1286 }
1287 unit_do_action(pplayer, punit->id, ptile->index,
1288 0, city_name_suggestion(pplayer, ptile),
1289 ACTION_FOUND_CITY);
1290 pcity = tile_city(ptile);
1291 if (!pcity && punit) {
1292 enum ane_kind reason = action_not_enabled_reason(punit,
1293 ACTION_FOUND_CITY,
1294 ptile, NULL, NULL);
1295
1296 if (reason == ANEK_CITY_TOO_CLOSE_TGT) {
1297 /* This is acceptable. A hut in the path to the tile may have created
1298 * a city that now is too close. */
1299 log_debug("%s: Failed to build city at (%d, %d)",
1300 player_name(pplayer), TILE_XY(ptile));
1301 } else {
1302 /* The request was illegal to begin with. */
1303 log_error("%s: Failed to build city at (%d, %d). Reason id: %d",
1304 player_name(pplayer), TILE_XY(ptile), reason);
1305 return CBE_FATAL;
1306 }
1307
1308 return CBE_RECOVERABLE;
1309 }
1310
1311 /* We have to rebuild at least the cache for this city. This event is
1312 * rare enough we might as well build the whole thing. Who knows what
1313 * else might be cached in the future? */
1314 fc_assert_ret_val(pplayer == city_owner(pcity), FALSE);
1315 initialize_infrastructure_cache(pplayer);
1316
1317 /* Init ai.choice. Handling ferryboats might use it. */
1318 adv_init_choice(&def_ai_city_data(pcity, ait)->choice);
1319
1320 return CBE_OK;
1321}
1322
1323/*************************************************************************/
1327 void contemplate_new_city(struct ai_type *ait, struct city *pcity)
1328{
1329 struct unit *virtualunit;
1330 struct tile *pcenter = city_tile(pcity);
1331 struct player *pplayer = city_owner(pcity);
1332 struct unit_type *unit_type;
1333
1334 if (game.scenario.prevent_new_cities) {
1335 return;
1336 }
1337
1338 unit_type = best_role_unit(pcity, action_id_get_role(ACTION_FOUND_CITY));
1339
1340 if (unit_type == NULL) {
1341 log_debug("No ACTION_FOUND_CITY role unit available");
1342 return;
1343 }
1344
1345 /* Create a localized "virtual" unit to do operations with. */
1346 virtualunit = unit_virtual_create(pplayer, pcity, unit_type, 0);
1347 unit_tile_set(virtualunit, pcenter);
1348
1349 if (is_ai(pplayer)) {
1350 struct cityresult *result;
1351 bool is_coastal = is_terrain_class_near_tile(&(wld.map), pcenter, TC_OCEAN);
1352 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1353
1354 result = find_best_city_placement(ait, virtualunit, is_coastal, is_coastal);
1355
1356 if (result) {
1357 fc_assert_ret(0 <= result->result); /* 'result' is not freed! */
1358
1359 CITY_LOG(LOG_DEBUG, pcity, "want(" ADV_WANT_PRINTF ") to establish city at"
1360 " (%d, %d) and will %s to get there", result->result,
1361 TILE_XY(result->tile),
1362 (result->virt_boat ? "build a boat" :
1363 (result->overseas ? "use a boat" : "walk")));
1364
1365 city_data->founder_want = (result->virt_boat ?
1366 -result->result : result->result);
1367 city_data->founder_boat = result->overseas;
1368
1369 cityresult_destroy(result);
1370 } else {
1371 CITY_LOG(LOG_DEBUG, pcity, "want no city");
1372 city_data->founder_want = 0;
1373 }
1374 } else {
1375 /* Always failing */
1376 fc_assert_ret(is_ai(pplayer));
1377 }
1378
1379 unit_virtual_destroy(virtualunit);
1380}
action_id_get_role
#define action_id_get_role(act_id)
Definition actions.h:451
ACTION_NONE
#define ACTION_NONE
Definition actions.h:55
adv_init_choice
void adv_init_choice(struct adv_choice *choice)
Definition advchoice.c:31
adv_data_get
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:604
advdata.h
adv_danger_at
bool adv_danger_at(struct unit *punit, struct tile *ptile)
Definition advgoto.c:425
advgoto.h
amortize
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
advtools.h
aiferry_find_boat
int aiferry_find_boat(struct ai_type *ait, struct unit *punit, int cap, struct pf_path **path)
Definition aiferry.c:495
dai_is_ferry
bool dai_is_ferry(struct unit *pferry, struct ai_type *ait)
Definition aiferry.c:159
aiferry.h
adv_unit_new_task
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
Definition autoworkers.c:1276
adv_worker_safe_tile
bool adv_worker_safe_tile(const struct civ_map *nmap, const struct player *pplayer, struct unit *punit, struct tile *ptile)
Definition autoworkers.c:1150
worker_evaluate_city_requests
struct city * worker_evaluate_city_requests(struct unit *punit, struct worker_task **best_task, struct pf_path **path, struct workermap *state)
Definition autoworkers.c:835
auto_worker_setup_work
bool auto_worker_setup_work(const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct workermap *state, int recursion, struct pf_path *path, struct tile *best_tile, enum unit_activity best_act, struct extra_type **best_target, int completion_time)
Definition autoworkers.c:1015
worker_evaluate_improvements
adv_want worker_evaluate_improvements(const struct civ_map *nmap, struct unit *punit, enum unit_activity *best_act, struct extra_type **best_target, struct tile **best_tile, struct pf_path **path, struct workermap *state)
Definition autoworkers.c:442
autoworkers.h
city_waste
int city_waste(const struct city *pcity, Output_type_id otype, int total, int *breakdown)
Definition city.c:3224
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
city_size_add
void city_size_add(struct city *pcity, int add)
Definition city.c:1160
citylog_map_data
void citylog_map_data(enum log_level level, int radius_sq, int *map_data)
Definition city.c:411
create_city_virtual
struct city * create_city_virtual(struct player *pplayer, struct tile *ptile, const char *name)
Definition city.c:3426
city_can_be_built_here
bool city_can_be_built_here(const struct civ_map *nmap, const struct tile *ptile, const struct unit *punit, bool hut_test)
Definition city.c:1483
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
destroy_city_virtual
void destroy_city_virtual(struct city *pcity)
Definition city.c:3512
city_choose_build_default
void city_choose_build_default(struct city *pcity)
Definition city.c:1083
city_tile_output
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
Definition city.c:1279
city_map_tiles
int city_map_tiles(int city_radius_sq)
Definition city.c:171
city.h
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_tile_iterate_index
#define city_tile_iterate_index(_nmap, _radius_sq, _city_tile, _tile, _index)
Definition city.h:201
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
city_tile_iterate_index_end
#define city_tile_iterate_index_end
Definition city.h:209
city_owner
#define city_owner(_pcity_)
Definition city.h:563
city_map_iterate_end
#define city_map_iterate_end
Definition city.h:177
city_map_iterate
#define city_map_iterate(_radius_sq, _index, _x, _y)
Definition city.h:173
citymap_reserve_tile
void citymap_reserve_tile(struct tile *ptile, int id)
Definition citymap.c:167
citymap_is_reserved
bool citymap_is_reserved(struct tile *ptile)
Definition citymap.c:190
citymap_read
int citymap_read(struct tile *ptile)
Definition citymap.c:181
citymap.h
city_name_suggestion
const char * city_name_suggestion(struct player *pplayer, struct tile *ptile)
Definition citytools.c:453
clear_worker_tasks
void clear_worker_tasks(struct city *pcity)
Definition citytools.c:3589
citytools.h
incite_cost
char * incite_cost
Definition comments.c:74
daicity.h
dai_plr_data_get
struct ai_plr * dai_plr_data_get(struct ai_type *ait, struct player *pplayer, bool *caller_closes)
Definition daidata.c:308
dai_data_phase_finished
void dai_data_phase_finished(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:285
daidata.h
dailog.h
TECH_LOG
#define TECH_LOG(ait, loglevel, pplayer, padvance, msg,...)
Definition dailog.h:36
daiplayer.h
def_ai_player_data
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition daiplayer.h:54
def_ai_city_data
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition daiplayer.h:42
def_ai_unit_data
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition daiplayer.h:48
PERFECTION
#define PERFECTION
Definition daisettler.c:104
GROWTH_PRIORITY
#define GROWTH_PRIORITY
Definition daisettler.c:98
dai_auto_settler_run
void dai_auto_settler_run(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct workermap *state)
Definition daisettler.c:1032
result_defense_bonus
static adv_want result_defense_bonus(struct player *pplayer, const struct cityresult *result)
Definition daisettler.c:596
tdc_plr_set
static void tdc_plr_set(struct ai_type *ait, struct player *plr, int tindex, const struct tile_data_cache *tdcache)
Definition daisettler.c:549
cb_error_level
cb_error_level
Definition daisettler.c:185
CBE_OK
@ CBE_OK
Definition daisettler.c:185
CBE_FATAL
@ CBE_FATAL
Definition daisettler.c:185
CBE_RECOVERABLE
@ CBE_RECOVERABLE
Definition daisettler.c:185
cityresult_new
static struct cityresult * cityresult_new(struct tile *ptile)
Definition daisettler.c:224
food_starvation
static bool food_starvation(const struct cityresult *result)
Definition daisettler.c:569
cityresult_fill
static struct cityresult * cityresult_fill(struct ai_type *ait, struct player *pplayer, struct tile *center)
Definition daisettler.c:275
RESULT_IS_ENOUGH
#define RESULT_IS_ENOUGH
Definition daisettler.c:94
GROWTH_POTENTIAL_DEEMPHASIS
#define GROWTH_POTENTIAL_DEEMPHASIS
Definition daisettler.c:109
print_cityresult
static void print_cityresult(struct player *pplayer, const struct cityresult *cr)
Definition daisettler.c:641
naval_bonus
static adv_want naval_bonus(const struct cityresult *result)
Definition daisettler.c:625
DEFENSE_EMPHASIS
#define DEFENSE_EMPHASIS
Definition daisettler.c:116
dai_auto_settler_init
void dai_auto_settler_init(struct ai_plr *ai)
Definition daisettler.c:1013
NAVAL_EMPHASIS
#define NAVAL_EMPHASIS
Definition daisettler.c:112
tile_data_cache_copy
struct tile_data_cache * tile_data_cache_copy(const struct tile_data_cache *ptdc)
Definition daisettler.c:484
dai_auto_settler_cont
void dai_auto_settler_cont(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct workermap *state)
Definition daisettler.c:1206
shield_starvation
static bool shield_starvation(const struct cityresult *result)
Definition daisettler.c:584
settler_map_iterate
static struct cityresult * settler_map_iterate(struct ai_type *ait, struct pf_parameter *parameter, struct unit *punit, int boat_cost)
Definition daisettler.c:790
dai_auto_settler_free
void dai_auto_settler_free(struct ai_plr *ai)
Definition daisettler.c:1250
FERRY_TECH_WANT
#define FERRY_TECH_WANT
Definition daisettler.c:96
dai_do_build_city
static enum cb_error_level dai_do_build_city(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daisettler.c:1266
cityresult_destroy
static void cityresult_destroy(struct cityresult *result)
Definition daisettler.c:257
dai_auto_settler_reset
void dai_auto_settler_reset(struct ai_type *ait, struct player *pplayer)
Definition daisettler.c:1219
city_desirability
struct cityresult * city_desirability(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *ptile)
Definition daisettler.c:713
tdc_plr_get
static const struct tile_data_cache * tdc_plr_get(struct ai_type *ait, struct player *plr, int tindex)
Definition daisettler.c:514
contemplate_new_city
void contemplate_new_city(struct ai_type *ait, struct city *pcity)
Definition daisettler.c:1327
find_best_city_placement
static struct cityresult * find_best_city_placement(struct ai_type *ait, struct unit *punit, bool look_for_boat, bool use_virt_boat)
Definition daisettler.c:896
tile_data_cache_destroy
static void tile_data_cache_destroy(struct tile_data_cache *ptdc)
Definition daisettler.c:504
tile_data_cache_new
struct tile_data_cache * tile_data_cache_new(void)
Definition daisettler.c:470
daisettler.h
dai_unit_new_task
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition daitools.c:641
dai_gothere
bool dai_gothere(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile)
Definition daitools.c:242
daitools.h
AIUNIT_BUILD_CITY
@ AIUNIT_BUILD_CITY
Definition daiunit.h:27
AIUNIT_NONE
@ AIUNIT_NONE
Definition daiunit.h:27
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
cost
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
ane_kind
ane_kind
Definition explanation.h:22
ANEK_CITY_TOO_CLOSE_TGT
@ ANEK_CITY_TOO_CLOSE_TGT
Definition explanation.h:83
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
adv_want
float adv_want
Definition fc_types.h:1335
AUT_BUILD_CITY
@ AUT_BUILD_CITY
Definition fc_types.h:374
AUT_AUTO_WORKER
@ AUT_AUTO_WORKER
Definition fc_types.h:374
ADV_WANT_PRINTF
#define ADV_WANT_PRINTF
Definition fc_types.h:1336
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_TRADE
@ O_TRADE
Definition fc_types.h:101
Continent_id
signed short Continent_id
Definition fc_types.h:376
BORDERS_DISABLED
@ BORDERS_DISABLED
Definition fc_types.h:1017
game
struct civ_game game
Definition game.c:61
wld
struct world wld
Definition game.c:62
game_unit_by_number
struct unit * game_unit_by_number(int id)
Definition game.c:115
game.h
government_of_player
struct government * government_of_player(const struct player *pplayer)
Definition government.c:114
government.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
initialize_infrastructure_cache
void initialize_infrastructure_cache(struct player *pplayer)
Definition infracache.c:250
infracache.h
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_test
#define log_test
Definition log.h:136
fc_assert
#define fc_assert(condition)
Definition log.h:176
LOG_TEST
#define LOG_TEST
Definition log.h:139
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
log_error
#define log_error(message,...)
Definition log.h:103
same_pos
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:950
map.h
square_iterate
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:377
square_iterate_end
#define square_iterate_end
Definition map.h:380
map_is_known
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:901
upgrade_city_extras
bool upgrade_city_extras(struct city *pcity, struct extra_type **gained)
Definition maphand.c:241
maphand.h
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
movement.h
packets.h
pf_path_last_position
const struct pf_position * pf_path_last_position(const struct pf_path *path)
Definition path_finding.c:3531
pf_path_destroy
void pf_path_destroy(struct pf_path *path)
Definition path_finding.c:3411
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
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:843
pft_fill_unit_overlap_param
void pft_fill_unit_overlap_param(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:894
no_fights_or_unknown
enum tile_behavior no_fights_or_unknown(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition pf_tools.c:493
pf_tools.h
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:895
pplayers_in_peace
bool pplayers_in_peace(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1430
player.h
is_ai
#define is_ai(plr)
Definition player.h:232
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
spechash.h
y
struct sprite int int y
Definition sprite_g.h:31
x
struct sprite int x
Definition sprite_g.h:31
srv_log.h
CITY_LOG
#define CITY_LOG(loglevel, pcity, msg,...)
Definition srv_log.h:83
UNIT_LOG
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
AIT_SETTLERS
@ AIT_SETTLERS
Definition srv_log.h:44
AIT_WORKERS
@ AIT_WORKERS
Definition srv_log.h:45
TIMER_STOP
@ TIMER_STOP
Definition srv_log.h:76
TIMER_START
@ TIMER_START
Definition srv_log.h:76
TIMING_LOG
#define TIMING_LOG(timer, activity)
Definition srv_log.h:125
adv_data
Definition advdata.h:50
adv_data::shield_priority
int shield_priority
Definition advdata.h:113
adv_data::food_priority
int food_priority
Definition advdata.h:114
adv_data::gov
struct government * gov
Definition advdata.h:131
adv_data::goal
struct adv_data::@93 goal
adv_data::govt
struct adv_data::@93::@95 govt
adv_data::science_priority
int science_priority
Definition advdata.h:117
ai_city
Definition daicity.h:34
ai_plr
Definition daidata.h:71
ai_plr::settler
struct ai_settler * settler
Definition daidata.h:101
ai_settler
Definition daisettler.c:143
ai_settler::tdc_hash
struct tile_data_cache_hash * tdc_hash
Definition daisettler.c:144
ai_type
Definition ai.h:50
city
Definition city.h:320
city::waste
int waste[O_LAST]
Definition city.h:356
cityresult
Definition daisettler.c:156
cityresult::tdc
struct tile_data_cache * tdc
Definition daisettler.c:166
cityresult::cindex
int cindex
Definition daisettler.c:172
cityresult::city_center
struct cityresult::@278 city_center
cityresult::waste
int waste
Definition daisettler.c:160
cityresult::corruption
int corruption
Definition daisettler.c:160
cityresult::total
adv_want total
Definition daisettler.c:158
cityresult::virt_boat
bool virt_boat
Definition daisettler.c:162
cityresult::best_other
struct cityresult::@279 best_other
cityresult::result
adv_want result
Definition daisettler.c:159
cityresult::overseas
bool overseas
Definition daisettler.c:161
cityresult::city_radius_sq
int city_radius_sq
Definition daisettler.c:182
cityresult::remaining
adv_want remaining
Definition daisettler.c:177
cityresult::tile
struct tile * tile
Definition daisettler.c:157
cityresult::tdc_hash
struct tile_data_cache_hash * tdc_hash
Definition daisettler.c:180
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::scenario
struct packet_scenario_info scenario
Definition game.h:87
civ_map
Definition map_types.h:71
extra_type
Definition extras.h:88
government
Definition government.h:52
packet_game_info::fulltradesize
int fulltradesize
Definition packets_gen.h:160
packet_game_info::borders
enum borders_mode borders
Definition packets_gen.h:133
packet_game_info::add_to_size_limit
int add_to_size_limit
Definition packets_gen.h:119
packet_game_info::init_city_radius_sq
int init_city_radius_sq
Definition packets_gen.h:188
packet_game_info::food_cost
int food_cost
Definition packets_gen.h:155
packet_game_info::turn
int turn
Definition packets_gen.h:245
packet_game_info::citymindist
int citymindist
Definition packets_gen.h:149
packet_scenario_info::prevent_new_cities
bool prevent_new_cities
Definition packets_gen.h:1597
pf_map
Definition path_finding.c:78
pf_parameter
Definition path_finding.h:357
pf_parameter::get_TB
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition path_finding.h:398
pf_parameter::move_rate
int move_rate
Definition path_finding.h:370
pf_parameter::omniscience
bool omniscience
Definition path_finding.h:376
pf_path
Definition path_finding.h:344
pf_position::turn
int turn
Definition path_finding.h:329
player
Definition player.h:249
player::government
struct government * government
Definition player.h:258
tile_data_cache
Definition daisettler.c:118
tile_data_cache::sum
int sum
Definition daisettler.c:123
tile_data_cache::reserved
int reserved
Definition daisettler.c:125
tile_data_cache::shield
short shield
Definition daisettler.c:121
tile_data_cache::trade
short trade
Definition daisettler.c:120
tile_data_cache::food
short food
Definition daisettler.c:119
tile_data_cache::turn
int turn
Definition daisettler.c:127
tile
Definition tile.h:50
tile::index
int index
Definition tile.h:51
unit_class
Definition unittype.h:149
unit_type
Definition unittype.h:507
unit
Definition unit.h:140
unit::moves_left
int moves_left
Definition unit.h:152
unit::id
int id
Definition unit.h:147
unit::debug
bool debug
Definition unit.h:237
unit::server
struct unit::@81::@84 server
unit::tile
struct tile * tile
Definition unit.h:142
unit::goto_tile
struct tile * goto_tile
Definition unit.h:157
worker_task
Definition workertask.h:21
workermap
Definition autoworkers.c:72
world::map
struct civ_map map
Definition world_object.h:38
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
advance_index
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
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:612
tile_virtual_destroy
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1035
tile_set_owner
void tile_set_owner(struct tile *ptile, struct player *pplayer, struct tile *claimer)
Definition tile.c:69
tile_virtual_new
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
tile_get_info_text
const char * tile_get_info_text(const struct tile *ptile, bool include_nuisances, int linebreaks)
Definition tile.c:771
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_set_worked
void tile_set_worked(struct tile *ptile, struct city *pcity)
Definition tile.c:106
tile_claimer
#define tile_claimer(_tile)
Definition tile.h:101
tile_index
#define tile_index(_pt_)
Definition tile.h:89
tile_worked
#define tile_worked(_tile)
Definition tile.h:115
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:111
TILE_XY
#define TILE_XY(ptile)
Definition tile.h:43
tile_continent
#define tile_continent(_tile)
Definition tile.h:93
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
tile_owner
#define tile_owner(_tile)
Definition tile.h:97
timing.h
unit_is_cityfounder
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2699
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:1662
unit_virtual_destroy
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1767
unit_tile_set
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1285
set_unit_activity
void set_unit_activity(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unit.c:1115
unit_tile
#define unit_tile(_pu)
Definition unit.h:397
CHECK_UNIT
#define CHECK_UNIT(punit)
Definition unit.h:273
unit_owner
#define unit_owner(_pu)
Definition unit.h:396
unit_activity_handling
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6613
unit_do_action
void unit_do_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id, const char *name, const action_id action_type)
Definition unithand.c:3317
action_not_enabled_reason
enum ane_kind action_not_enabled_reason(struct unit *punit, action_id act_id, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Definition unithand.c:1935
unithand.h
send_unit_info
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2878
unittools.h
best_role_unit
struct unit_type * best_role_unit(const struct city *pcity, int role)
Definition unittype.c:2271
get_role_unit
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2253
unit_build_shield_cost_base
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1484
best_role_unit_for_player
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2297
utype_rule_name
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
unit_class_get
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2498
unit_has_type_flag
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
unit_pop_value
int unit_pop_value(const struct unit *punit)
Definition unittype.c:1543
unit_tech_reqs_iterate_end
#define unit_tech_reqs_iterate_end
Definition unittype.h:885
unit_tech_reqs_iterate
#define unit_tech_reqs_iterate(_utype_, _p)
Definition unittype.h:879
MOVE_NONE
@ MOVE_NONE
Definition unittype.h:144