1 /***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Project
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 /* common */
19 #include "game.h"
20 #include "government.h"
21 #include "map.h"
22 #include "multipliers.h"
23 #include "research.h"
24
25 /* server */
26 #include "cityturn.h"
27 #include "plrhand.h"
28
29 /* server/advisors */
30 #include "advdata.h"
31
32 /* ai/default */
33 #include "aicity.h"
34 #include "aiferry.h"
35 #include "aiplayer.h"
36 #include "aisettler.h"
37 #include "aiunit.h"
38 #include "daidiplomacy.h"
39 #include "daieffects.h"
40
41 #include "aidata.h"
42
43 static void dai_diplomacy_new(struct ai_type *ait,
44 const struct player *plr1,
45 const struct player *plr2);
46 static void dai_diplomacy_defaults(struct ai_type *ait,
47 const struct player *plr1,
48 const struct player *plr2);
49 static void dai_diplomacy_destroy(struct ai_type *ait,
50 const struct player *plr1,
51 const struct player *plr2);
52
53 /****************************************************************************
54 Initialize ai data structure
55 ****************************************************************************/
dai_data_init(struct ai_type * ait,struct player * pplayer)56 void dai_data_init(struct ai_type *ait, struct player *pplayer)
57 {
58 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
59
60 ai->phase_initialized = FALSE;
61
62 ai->last_num_continents = -1;
63 ai->last_num_oceans = -1;
64
65 ai->diplomacy.player_intel_slots
66 = fc_calloc(player_slot_count(),
67 sizeof(*ai->diplomacy.player_intel_slots));
68 player_slots_iterate(pslot) {
69 const struct ai_dip_intel **player_intel_slot
70 = ai->diplomacy.player_intel_slots + player_slot_index(pslot);
71 *player_intel_slot = NULL;
72 } player_slots_iterate_end;
73
74 players_iterate(aplayer) {
75 /* create ai diplomacy states for all other players */
76 dai_diplomacy_new(ait, pplayer, aplayer);
77 dai_diplomacy_defaults(ait, pplayer, aplayer);
78 /* create ai diplomacy state of this player */
79 if (aplayer != pplayer) {
80 dai_diplomacy_new(ait, aplayer, pplayer);
81 dai_diplomacy_defaults(ait, aplayer, pplayer);
82 }
83 } players_iterate_end;
84
85 ai->diplomacy.strategy = WIN_OPEN;
86 ai->diplomacy.timer = 0;
87 ai->diplomacy.love_coeff = 4; /* 4% */
88 ai->diplomacy.love_incr = MAX_AI_LOVE * 3 / 100;
89 ai->diplomacy.req_love_for_peace = MAX_AI_LOVE / 8;
90 ai->diplomacy.req_love_for_alliance = MAX_AI_LOVE / 4;
91
92 ai->settler = NULL;
93
94 /* Initialise autosettler. */
95 dai_auto_settler_init(ai);
96 }
97
98 /****************************************************************************
99 Deinitialize ai data structure
100 ****************************************************************************/
dai_data_close(struct ai_type * ait,struct player * pplayer)101 void dai_data_close(struct ai_type *ait, struct player *pplayer)
102 {
103 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
104
105 /* Finish the phase if it's open - free resources related to
106 * open/finish cycle */
107 dai_data_phase_finished(ait, pplayer);
108
109 /* Free autosettler. */
110 dai_auto_settler_free(ai);
111
112 if (ai->diplomacy.player_intel_slots != NULL) {
113 players_iterate(aplayer) {
114 /* destroy the ai diplomacy states of this player with others ... */
115 dai_diplomacy_destroy(ait, pplayer, aplayer);
116 /* and of others with this player. */
117 if (aplayer != pplayer) {
118 dai_diplomacy_destroy(ait, aplayer, pplayer);
119 }
120 } players_iterate_end;
121 free(ai->diplomacy.player_intel_slots);
122 }
123 }
124
125 /**************************************************************************
126 Return whether data phase is currently open. Data phase is open
127 between dai_data_phase_begin() and dai_data_phase_finished() calls.
128 **************************************************************************/
is_ai_data_phase_open(struct ai_type * ait,struct player * pplayer)129 bool is_ai_data_phase_open(struct ai_type *ait, struct player *pplayer)
130 {
131 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
132
133 return ai->phase_initialized;
134 }
135
136 /****************************************************************************
137 Make and cache lots of calculations needed for other functions.
138 ****************************************************************************/
dai_data_phase_begin(struct ai_type * ait,struct player * pplayer,bool is_new_phase)139 void dai_data_phase_begin(struct ai_type *ait, struct player *pplayer,
140 bool is_new_phase)
141 {
142 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
143 bool caller_closes;
144
145 /* Note that this refreshes advisor data if needed. ai_plr_data_get()
146 is expected to refresh advisor data if needed, and ai_plr_data_get()
147 depends on this call
148 ai_plr_data_get()->ai_data_phase_begin()->adv_data_get() to do it.
149 If you change this, you may need to adjust ai_plr_data_get() also. */
150 struct adv_data *adv;
151
152 if (ai->phase_initialized) {
153 return;
154 }
155
156 ai->phase_initialized = TRUE;
157
158 adv = adv_data_get(pplayer, &caller_closes);
159
160 /* Store current number of known continents and oceans so we can compare
161 against it later in order to see if ai data needs refreshing. */
162 ai->last_num_continents = adv->num_continents;
163 ai->last_num_oceans = adv->num_oceans;
164
165 /*** Diplomacy ***/
166 if (pplayer->ai_controlled && !is_barbarian(pplayer) && is_new_phase) {
167 dai_diplomacy_begin_new_phase(ait, pplayer);
168 }
169
170 /* Set per-player variables. We must set all players, since players
171 * can be created during a turn, and we don't want those to have
172 * invalid values. */
173 players_iterate(aplayer) {
174 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
175
176 adip->is_allied_with_enemy = NULL;
177 adip->at_war_with_ally = NULL;
178 adip->is_allied_with_ally = NULL;
179
180 players_iterate(check_pl) {
181 if (check_pl == pplayer
182 || check_pl == aplayer
183 || !check_pl->is_alive) {
184 continue;
185 }
186 if (pplayers_allied(aplayer, check_pl)
187 && player_diplstate_get(pplayer, check_pl)->type == DS_WAR) {
188 adip->is_allied_with_enemy = check_pl;
189 }
190 if (pplayers_allied(pplayer, check_pl)
191 && player_diplstate_get(aplayer, check_pl)->type == DS_WAR) {
192 adip->at_war_with_ally = check_pl;
193 }
194 if (pplayers_allied(aplayer, check_pl)
195 && pplayers_allied(pplayer, check_pl)) {
196 adip->is_allied_with_ally = check_pl;
197 }
198 } players_iterate_end;
199 } players_iterate_end;
200
201 /*** Statistics ***/
202
203 ai->stats.workers = fc_calloc(adv->num_continents + 1, sizeof(int));
204 unit_list_iterate(pplayer->units, punit) {
205 struct tile *ptile = unit_tile(punit);
206
207 if (!is_ocean_tile(ptile) && unit_has_type_flag(punit, UTYF_SETTLERS)) {
208 ai->stats.workers[(int)tile_continent(unit_tile(punit))]++;
209 }
210 } unit_list_iterate_end;
211
212 BV_CLR_ALL(ai->stats.diplomat_reservations);
213 unit_list_iterate(pplayer->units, punit) {
214 if ((unit_can_do_action(punit, ACTION_SPY_POISON)
215 || unit_can_do_action(punit, ACTION_SPY_SABOTAGE_CITY)
216 || unit_can_do_action(punit, ACTION_SPY_TARGETED_SABOTAGE_CITY)
217 || unit_can_do_action(punit, ACTION_SPY_INCITE_CITY)
218 || unit_can_do_action(punit, ACTION_ESTABLISH_EMBASSY)
219 || unit_can_do_action(punit, ACTION_SPY_STEAL_TECH)
220 || unit_can_do_action(punit, ACTION_SPY_TARGETED_STEAL_TECH)
221 || unit_can_do_action(punit, ACTION_SPY_INVESTIGATE_CITY)
222 || unit_can_do_action(punit, ACTION_SPY_STEAL_GOLD))
223 && def_ai_unit_data(punit, ait)->task == AIUNIT_ATTACK) {
224
225 fc_assert_msg(punit->goto_tile != NULL, "No target city for spy action");
226
227 if (punit->goto_tile != NULL) {
228 struct city *pcity = tile_city(punit->goto_tile);
229
230 if (pcity != NULL) {
231 /* Heading somewhere on a mission, reserve target. */
232 BV_SET(ai->stats.diplomat_reservations, pcity->id);
233 }
234 }
235 }
236 } unit_list_iterate_end;
237
238 aiferry_init_stats(ait, pplayer);
239
240 /*** Interception engine ***/
241
242 /* We are tracking a unit if punit->server.ai->cur_pos is not NULL. If we
243 * are not tracking, start tracking by setting cur_pos. If we are,
244 * fill prev_pos with previous cur_pos. This way we get the
245 * necessary coordinates to calculate a probable trajectory. */
246 players_iterate_alive(aplayer) {
247 if (aplayer == pplayer) {
248 continue;
249 }
250 unit_list_iterate(aplayer->units, punit) {
251 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
252
253 if (!unit_data->cur_pos) {
254 /* Start tracking */
255 unit_data->cur_pos = &unit_data->cur_struct;
256 unit_data->prev_pos = NULL;
257 } else {
258 unit_data->prev_struct = unit_data->cur_struct;
259 unit_data->prev_pos = &unit_data->prev_struct;
260 }
261 *unit_data->cur_pos = unit_tile(punit);
262 } unit_list_iterate_end;
263 } players_iterate_alive_end;
264
265 if (caller_closes) {
266 adv_data_phase_done(pplayer);
267 }
268 }
269
270 /****************************************************************************
271 Clean up ai data after phase finished.
272 ****************************************************************************/
dai_data_phase_finished(struct ai_type * ait,struct player * pplayer)273 void dai_data_phase_finished(struct ai_type *ait, struct player *pplayer)
274 {
275 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
276
277 if (!ai->phase_initialized) {
278 return;
279 }
280
281 free(ai->stats.workers);
282 ai->stats.workers = NULL;
283
284 ai->phase_initialized = FALSE;
285 }
286
287 /****************************************************************************
288 Get current default ai data related to player.
289 If close is set, data phase will be opened even if it's currently closed,
290 and the boolean will be set accordingly to tell caller that phase needs
291 closing.
292 ****************************************************************************/
dai_plr_data_get(struct ai_type * ait,struct player * pplayer,bool * caller_closes)293 struct ai_plr *dai_plr_data_get(struct ai_type *ait, struct player *pplayer,
294 bool *caller_closes)
295 {
296 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
297
298 fc_assert_ret_val(ai != NULL, NULL);
299
300 /* This assert really is required. See longer comment
301 in adv_data_get() for equivalent code. */
302 #if defined(FREECIV_DEBUG) || defined(IS_DEVEL_VERSION)
303 fc_assert(caller_closes != NULL || ai->phase_initialized);
304 #endif
305
306 if (caller_closes != NULL) {
307 *caller_closes = FALSE;
308 }
309
310 if (ai->last_num_continents != game.map.num_continents
311 || ai->last_num_oceans != game.map.num_oceans) {
312 /* We have discovered more continents, recalculate! */
313
314 /* See adv_data_get() */
315 if (ai->phase_initialized) {
316 dai_data_phase_finished(ait, pplayer);
317 dai_data_phase_begin(ait, pplayer, FALSE);
318 } else {
319 /* wrong order */
320 log_debug("%s ai data phase closed when dai_plr_data_get() called",
321 player_name(pplayer));
322 dai_data_phase_begin(ait, pplayer, FALSE);
323 if (caller_closes != NULL) {
324 *caller_closes = TRUE;
325 } else {
326 dai_data_phase_finished(ait, pplayer);
327 }
328 }
329 } else {
330 if (!ai->phase_initialized && caller_closes != NULL) {
331 dai_data_phase_begin(ait, pplayer, FALSE);
332 *caller_closes = TRUE;
333 }
334 }
335
336 return ai;
337 }
338
339 /****************************************************************************
340 Allocate new ai diplomacy slot
341 ****************************************************************************/
dai_diplomacy_new(struct ai_type * ait,const struct player * plr1,const struct player * plr2)342 static void dai_diplomacy_new(struct ai_type *ait,
343 const struct player *plr1,
344 const struct player *plr2)
345 {
346 struct ai_dip_intel *player_intel;
347
348 fc_assert_ret(plr1 != NULL);
349 fc_assert_ret(plr2 != NULL);
350
351 const struct ai_dip_intel **player_intel_slot
352 = def_ai_player_data(plr1, ait)->diplomacy.player_intel_slots
353 + player_index(plr2);
354
355 fc_assert_ret(*player_intel_slot == NULL);
356
357 player_intel = fc_calloc(1, sizeof(*player_intel));
358 *player_intel_slot = player_intel;
359 }
360
361 /****************************************************************************
362 Set diplomacy data between two players to its default values.
363 ****************************************************************************/
dai_diplomacy_defaults(struct ai_type * ait,const struct player * plr1,const struct player * plr2)364 static void dai_diplomacy_defaults(struct ai_type *ait,
365 const struct player *plr1,
366 const struct player *plr2)
367 {
368 struct ai_dip_intel *player_intel = dai_diplomacy_get(ait, plr1, plr2);
369
370 fc_assert_ret(player_intel != NULL);
371
372 /* pseudorandom value */
373 player_intel->spam = (player_index(plr1) + player_index(plr2)) % 5;
374 player_intel->countdown = -1;
375 player_intel->war_reason = WAR_REASON_NONE;
376 player_intel->distance = 1;
377 player_intel->ally_patience = 0;
378 player_intel->asked_about_peace = 0;
379 player_intel->asked_about_alliance = 0;
380 player_intel->asked_about_ceasefire = 0;
381 player_intel->warned_about_space = 0;
382 }
383
384 /***************************************************************
385 Returns diplomatic state type between two players
386 ***************************************************************/
dai_diplomacy_get(struct ai_type * ait,const struct player * plr1,const struct player * plr2)387 struct ai_dip_intel *dai_diplomacy_get(struct ai_type *ait,
388 const struct player *plr1,
389 const struct player *plr2)
390 {
391 fc_assert_ret_val(plr1 != NULL, NULL);
392 fc_assert_ret_val(plr2 != NULL, NULL);
393
394 const struct ai_dip_intel **player_intel_slot
395 = def_ai_player_data(plr1, ait)->diplomacy.player_intel_slots
396 + player_index(plr2);
397
398 fc_assert_ret_val(player_intel_slot != NULL, NULL);
399
400 return (struct ai_dip_intel *) *player_intel_slot;
401 }
402
403 /****************************************************************************
404 Free resources allocated for diplomacy information between two players.
405 ****************************************************************************/
dai_diplomacy_destroy(struct ai_type * ait,const struct player * plr1,const struct player * plr2)406 static void dai_diplomacy_destroy(struct ai_type *ait,
407 const struct player *plr1,
408 const struct player *plr2)
409 {
410 fc_assert_ret(plr1 != NULL);
411 fc_assert_ret(plr2 != NULL);
412
413 const struct ai_dip_intel **player_intel_slot
414 = def_ai_player_data(plr1, ait)->diplomacy.player_intel_slots
415 + player_index(plr2);
416
417 if (*player_intel_slot != NULL) {
418 free(dai_diplomacy_get(ait, plr1, plr2));
419 }
420
421 *player_intel_slot = NULL;
422 }
423
424 /****************************************************************************
425 Adjust multiplier values.
426 ****************************************************************************/
dai_adjust_policies(struct ai_type * ait,struct player * pplayer)427 void dai_adjust_policies(struct ai_type *ait, struct player *pplayer)
428 {
429 bool needs_back_rearrange = FALSE;
430 struct adv_data *adv;
431
432 adv = adv_data_get(pplayer, NULL);
433
434 multipliers_iterate(ppol) {
435 int orig_value = 0;
436 int mp_val = player_multiplier_value(pplayer, ppol);
437 int pidx = multiplier_index(ppol);
438 bool better_found = FALSE;
439
440 city_list_iterate(pplayer->cities, pcity) {
441 orig_value += dai_city_want(pplayer, pcity, adv, NULL);
442 } city_list_iterate_end;
443
444 /* Consider reducing policy value */
445 if (mp_val > ppol->start) {
446 int new_value = 0;
447
448 pplayer->multipliers[pidx] = MAX(mp_val - ppol->step, ppol->start);
449
450 city_list_iterate(pplayer->cities, acity) {
451 auto_arrange_workers(acity);
452 } city_list_iterate_end;
453
454 city_list_iterate(pplayer->cities, pcity) {
455 new_value += dai_city_want(pplayer, pcity, adv, NULL);
456 } city_list_iterate_end;
457
458 if (new_value > orig_value) {
459 /* This is step to right direction, leave it in effect. */
460 pplayer->multipliers_target[pidx] = pplayer->multipliers[pidx];
461
462 needs_back_rearrange = FALSE;
463 better_found = TRUE;
464 }
465 }
466
467 /* Consider increasing policy value */
468 if (!better_found && mp_val < ppol->stop) {
469 int new_value = 0;
470
471 pplayer->multipliers[pidx] = MIN(mp_val + ppol->step, ppol->stop);
472
473 city_list_iterate(pplayer->cities, acity) {
474 auto_arrange_workers(acity);
475 } city_list_iterate_end;
476
477 city_list_iterate(pplayer->cities, pcity) {
478 new_value += dai_city_want(pplayer, pcity, adv, NULL);
479 } city_list_iterate_end;
480
481 if (new_value > orig_value) {
482 /* This is step to right direction, leave it in effect. */
483 pplayer->multipliers_target[pidx] = pplayer->multipliers[pidx];
484
485 needs_back_rearrange = FALSE;
486 better_found = TRUE;
487 }
488 }
489
490 if (!better_found) {
491 /* Restore original multiplier value */
492 pplayer->multipliers[pidx] = mp_val;
493 needs_back_rearrange = TRUE;
494 }
495 } multipliers_iterate_end;
496
497 if (needs_back_rearrange) {
498 city_list_iterate(pplayer->cities, acity) {
499 auto_arrange_workers(acity);
500 } city_list_iterate_end;
501 }
502 }
503
504 /****************************************************************************
505 Set value of the government.
506 ****************************************************************************/
dai_gov_value(struct ai_type * ait,struct player * pplayer,struct government * gov,adv_want * val,bool * override)507 void dai_gov_value(struct ai_type *ait, struct player *pplayer,
508 struct government *gov, adv_want *val, bool *override)
509 {
510 int dist;
511 int bonus = 0; /* in percentage */
512 int revolution_turns;
513 struct universal source = { .kind = VUT_GOVERNMENT, .value.govern = gov };
514 struct adv_data *adv;
515 int turns = 9999; /* TODO: Set to correct value */
516 int nplayers;
517 const struct research *presearch;
518
519 /* Use default handling of no-cities case */
520 if (city_list_size(pplayer->cities) == 0) {
521 *override = FALSE;
522 return;
523 }
524
525 adv = adv_data_get(pplayer, NULL);
526 nplayers = normal_player_count();
527 presearch = research_get(pplayer);
528
529 pplayer->government = gov;
530 /* Ideally we should change tax rates here, but since
531 * this is a rather big CPU operation, we'd rather not. */
532 check_player_max_rates(pplayer);
533 city_list_iterate(pplayer->cities, acity) {
534 auto_arrange_workers(acity);
535 } city_list_iterate_end;
536 city_list_iterate(pplayer->cities, pcity) {
537 bool capital;
538
539 *val += dai_city_want(pplayer, pcity, adv, NULL);
540 capital = is_capital(pcity);
541
542 effect_list_iterate(get_req_source_effects(&source), peffect) {
543 bool present = TRUE;
544 bool active = TRUE;
545
546 requirement_vector_iterate(&peffect->reqs, preq) {
547 /* Check if all the requirements for the currently evaluated effect
548 * are met, except for having the tech that we are evaluating.
549 * TODO: Consider requirements that could be met later. */
550 if (VUT_GOVERNMENT == preq->source.kind
551 && preq->source.value.govern == gov) {
552 present = preq->present;
553 continue;
554 }
555 if (!is_req_active(pplayer, NULL, pcity, NULL, NULL, NULL, NULL,
556 NULL, NULL, preq, RPT_POSSIBLE)) {
557 active = FALSE;
558 break; /* presence doesn't matter for inactive effects. */
559 }
560
561 } requirement_vector_iterate_end;
562
563 if (active) {
564 adv_want v1;
565
566 v1 = dai_effect_value(pplayer, gov, adv, pcity, capital,
567 turns, peffect, 1,
568 nplayers);
569
570 if (!present) {
571 /* Government removes the effect */
572 *val -= v1;
573 } else {
574 *val += v1;
575 }
576 }
577 } effect_list_iterate_end;
578 } city_list_iterate_end;
579
580 bonus += adv_gov_action_immunity_want(gov);
581 bonus += adv_gov_player_bonus_want(pplayer);
582
583 revolution_turns = get_player_bonus(pplayer, EFT_REVOLUTION_UNHAPPINESS);
584 if (revolution_turns > 0) {
585 bonus -= 6 / revolution_turns;
586 }
587
588 *val += (*val * bonus) / 100;
589
590 /* FIXME: handle reqs other than technologies. */
591 dist = 0;
592 requirement_vector_iterate(&gov->reqs, preq) {
593 if (VUT_ADVANCE == preq->source.kind) {
594 dist += MAX(1, research_goal_unknown_techs(presearch,
595 advance_number(preq->source.value.advance)));
596 }
597 } requirement_vector_iterate_end;
598 *val = amortize(*val, dist);
599
600 *override = TRUE;
601 }
602