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

Freeciv-3.3

Loading...
Searching...
No Matches
aihand.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 "distribute.h"
20#include "log.h"
21#include "shared.h"
22#include "timing.h"
23
24/* common */
25#include "city.h"
26#include "game.h"
27#include "government.h"
28#include "map.h"
29#include "nation.h"
30#include "packets.h"
31#include "player.h"
32#include "research.h"
33#include "unit.h"
34#include "victory.h"
35
36/* common/aicore */
37#include "cm.h"
38
39/* server */
40#include "citytools.h"
41#include "cityturn.h"
42#include "plrhand.h"
43#include "sernet.h"
44#include "spacerace.h"
45#include "srv_log.h"
46#include "unithand.h"
47
48/* server/advisors */
49#include "advdata.h"
50#include "advspace.h"
51#include "advtools.h"
52
53/* ai */
54#include "handicaps.h"
55
56/* ai/default */
57#include "daicity.h"
58#include "daidata.h"
59#include "daidiplomacy.h"
60#include "dailog.h"
61#include "daimilitary.h"
62#include "daiplayer.h"
63#include "daitech.h"
64#include "daitools.h"
65
66#include "aihand.h"
67
68/*****************************************************************************
69 A man builds a city
70 With banks and cathedrals
71 A man melts the sand so he can
72 See the world outside
73 A man makes a car
74 And builds a road to run them on
75 A man dreams of leaving
76 but he always stays behind
77 And these are the days when our work has come assunder
78 And these are the days when we look for something other
79 /U2 Lemon.
80*****************************************************************************/
81
82#define LOGLEVEL_TAX LOG_DEBUG
83
84/* When setting rates, we accept negative balance if we have a lot of
85 * gold/bulb reserves. This is how long time gold/bulb reserves should last.
86 * For city grow due to rapture turns_for_rapture is added. */
87#define AI_GOLD_RESERVE_MIN_TURNS 10
88#define AI_BULBS_RESERVE_MIN_TURNS 10
89
90/* This factor is used for the delta between the estimated and real income to
91 * get 'real' rates for the AI player. */
92#define PCT_DELTA_TAX 50
93#define PCT_DELTA_SCI 10
94
95/*************************************************************************/
98 static void dai_manage_spaceship(struct player *pplayer)
99{
100 if (victory_enabled(VC_SPACERACE)) {
101 if (pplayer->spaceship.state == SSHIP_STARTED) {
102 adv_spaceship_autoplace(pplayer, &pplayer->spaceship);
103
104 /* if we have built the best possible spaceship -- AJS 19990610 */
105 if ((pplayer->spaceship.structurals == NUM_SS_STRUCTURALS)
106 && (pplayer->spaceship.components == NUM_SS_COMPONENTS)
107 && (pplayer->spaceship.modules == NUM_SS_MODULES))
108 handle_spaceship_launch(pplayer);
109 }
110 }
111}
112
113/*************************************************************************/
117 void dai_calc_data(const struct player *pplayer, int *trade, int *expenses,
118 int *income)
119{
120 if (NULL != trade) {
121 *trade = 0;
122 }
123 if (NULL != expenses) {
124 *expenses = 0;
125 }
126 if (NULL != income) {
127 *income = 0;
128 }
129
130 /* Find total trade surplus, gold expenses, and gold income */
131 city_list_iterate(pplayer->cities, pcity) {
132 if (NULL != trade) {
133 *trade += pcity->surplus[O_TRADE];
134 }
135
136 if (NULL != expenses) {
137 *expenses += pcity->usage[O_GOLD];
138 }
139
140 if (NULL != income) {
141 /* Also the immediately used gold is part of income, not only surplus */
142 *income += pcity->usage[O_GOLD] + pcity->surplus[O_GOLD];
143 }
144 } city_list_iterate_end;
145
146 switch (game.info.gold_upkeep_style) {
147 case GOLD_UPKEEP_CITY:
148 break;
149 case GOLD_UPKEEP_MIXED:
150 case GOLD_UPKEEP_NATION:
151 /* Account for units with gold upkeep paid for by the nation. */
152 unit_list_iterate(pplayer->units, punit) {
153 *expenses += punit->upkeep[O_GOLD];
154 } unit_list_iterate_end;
155 break;
156 }
157}
158
159/*****************************************************************************
160 Additional data needed for the AI rates calculation
161*****************************************************************************/
162enum {
163 AI_RATE_SCI = 0,
164 AI_RATE_TAX,
165 AI_RATE_LUX,
166 AI_RATE_COUNT
167};
168
169 enum celebration {
170 AI_CELEBRATION_UNCHECKED,
171 AI_CELEBRATION_NO,
172 AI_CELEBRATION_YES,
173};
174
175#define RATE_NOT_SET -1
176#define RATE_VALID(_rate) \
177 (_rate != RATE_NOT_SET)
178#define RATE_REMAINS(_rates) \
179 MAX(0, 100 - _rates[AI_RATE_SCI] - _rates[AI_RATE_TAX] \
180 - _rates[AI_RATE_LUX])
181
182/*************************************************************************/
211 static void dai_manage_taxes(struct ai_type *ait, struct player *pplayer)
212{
213 int maxrate = (has_handicap(pplayer, H_RATES)
214 ? get_player_bonus(pplayer, EFT_MAX_RATES) : 100);
215 struct research *research = research_get(pplayer);
216 enum celebration celebrate = AI_CELEBRATION_UNCHECKED;
217 struct adv_data *ai = adv_data_get(pplayer, NULL);
218 int can_celebrate = 0, total_cities = 0;
219 int trade = 0; /* total amount of trade generated */
220 int expenses = 0; /* total amount of gold upkeep */
221 int income = 0; /* total amount of gold income */
222 int turns_for_rapture; /* additional reserve needed for rapture */
223 unsigned rates_save[AI_RATE_COUNT], rates_tmp[AI_RATE_COUNT];
224 int rates[AI_RATE_COUNT];
225 int result[AI_RATE_COUNT];
226 int rate_tax_min = RATE_NOT_SET;
227 int rate_tax_balance = RATE_NOT_SET;
228 int rate_sci_min = RATE_NOT_SET;
229 int rate_sci_balance = RATE_NOT_SET;
230 int rate_lux_min_celebrate = maxrate;
231 int delta_tax = 0, delta_sci = 0;
232
233#ifdef DEBUG_TIMERS
234 struct timer *taxtimer = NULL;
235#endif
236
237 struct cm_parameter cmp;
238
239 if (!game.info.changable_tax) {
240 return; /* This ruleset does not support changing tax rates. */
241 }
242
243 maxrate = CLIP(34, maxrate, 100);
244
245 if (government_of_player(pplayer) == game.government_during_revolution) {
246 return; /* This government does not support changing tax rates. */
247 }
248
249#ifdef DEBUG_TIMERS
250 taxtimer = timer_new(TIMER_CPU, TIMER_DEBUG, "AI tax");
251 timer_start(taxtimer);
252#endif /* DEBUG_TIMERS */
253
254 /* City parameters needed for celebrations. */
255 cm_init_parameter(&cmp);
256 cmp.require_happy = TRUE; /* note this one */
257 cmp.allow_disorder = FALSE;
258 cmp.allow_specialists = TRUE;
259 cmp.factor[O_FOOD] = 20;
260 cmp.minimal_surplus[O_GOLD] = -FC_INFINITY;
261
262 /* Define reserve (gold/bulbs) needed for rapture (celebration). */
263 turns_for_rapture = ai->celebrate ? 0 : (game.info.rapturedelay + 1) * 3;
264
265 log_base(LOGLEVEL_TAX, "%s [max] rate=%d", player_name(pplayer), maxrate);
266
267 /* Save AI rates. */
268 rates_save[AI_RATE_SCI] = pplayer->economic.science;
269 rates_save[AI_RATE_TAX] = pplayer->economic.tax;
270 rates_save[AI_RATE_LUX] = pplayer->economic.luxury;
271
272 log_base(LOGLEVEL_TAX, "%s [old] (Sci/Lux/Tax)=%d/%d/%d",
273 player_name(pplayer), rates_save[AI_RATE_SCI],
274 rates_save[AI_RATE_LUX], rates_save[AI_RATE_TAX]);
275
276 /* Get some data for the AI player. */
277 dai_calc_data(pplayer, &trade, &expenses, &income);
278
279 /* Get the estimates for tax with the current rates. */
280 distribute(trade, AI_RATE_COUNT, rates_save, result);
281
282 /* The delta between the estimate and the real value. */
283 delta_tax = (result[AI_RATE_TAX] - expenses) - income;
284
285 log_base(LOGLEVEL_TAX, "%s [tax] estimated=%d real=%d (delta=%d)",
286 player_name(pplayer), result[AI_RATE_TAX] - expenses, income,
287 delta_tax);
288
289 /* Find minimum tax rate which gives us a positive balance for gold and
290 * science. We assume that we want science most and luxuries least here,
291 * and reverse or modify this assumption later.
292 * Furthermore, We assume our entire civilization is one big city, and
293 * distribute total income accordingly. This is a simplification that speeds
294 * up the code significantly. */
295
296 /* === Gold === */
297
298 /* First set tax (gold) to the minimal available number */
299 rates[AI_RATE_SCI] = maxrate; /* Assume we want science here */
300 rates[AI_RATE_TAX] = MAX(0, 100 - maxrate * 2); /* If maxrate < 50% */
301 rates[AI_RATE_LUX] = (100 - rates[AI_RATE_SCI] - rates[AI_RATE_TAX]);
302
303 /* Now find the minimum tax with positive gold balance
304 * Negative balance is acceptable if we have a lot of gold. */
305
306 log_base(LOGLEVEL_TAX, "%s [tax] trade=%d gold=%d expenses=%d",
307 player_name(pplayer), trade, pplayer->economic.gold, expenses);
308
309 while (rates[AI_RATE_TAX] <= maxrate
310 && rates[AI_RATE_SCI] >= 0
311 && rates[AI_RATE_LUX] >= 0) {
312 bool refill_coffers = pplayer->economic.gold < dai_gold_reserve(pplayer);
313 int balance_tax, balance_tax_min;
314 int i;
315
316 for (i = 0; i < AI_RATE_COUNT; i++) {
317 fc_assert(rates[i] >= 0);
318 rates_tmp[i] = rates[i];
319 }
320 distribute(trade, AI_RATE_COUNT, rates_tmp, result);
321
322 /* Consider the delta between the result and the real value from the
323 * last turn to get better estimates. */
324 balance_tax = (result[AI_RATE_TAX] - expenses)
325 - delta_tax * PCT_DELTA_TAX / 100;
326 balance_tax_min = -(pplayer->economic.gold
327 / (AI_GOLD_RESERVE_MIN_TURNS + turns_for_rapture));
328
329 log_base(LOGLEVEL_TAX, "%s [tax] Tax=%d income=%d",
330 player_name(pplayer), rates[AI_RATE_TAX], balance_tax);
331
332 if (!RATE_VALID(rate_tax_min) && balance_tax > balance_tax_min) {
333 /* Just slightly negative; we can afford that for a while */
334 rate_tax_min = rates[AI_RATE_TAX];
335 }
336
337 if (expenses == 0 || balance_tax > 0) {
338 /* Ok, got no expenses or positive balance */
339 if (refill_coffers && rates[AI_RATE_TAX] < maxrate) {
340 /* Need to refill coffers, increase tax a bit */
341 rates[AI_RATE_TAX] += 10;
342 if (rates[AI_RATE_LUX] > 0) {
343 rates[AI_RATE_LUX] -= 10;
344 } else {
345 rates[AI_RATE_SCI] -= 10;
346 }
347
348 log_base(LOGLEVEL_TAX, "%s [tax] Tax=%d to refill coffers",
349 player_name(pplayer), rates[AI_RATE_TAX]);
350 }
351
352 /* This is the minimum rate for a balanced treasury (gold). */
353 rate_tax_balance = rates[AI_RATE_TAX];
354
355 /* Done! Break the while loop */
356 break;
357 }
358
359 /* Negative balance. Unacceptable - increase tax. */
360 rates[AI_RATE_TAX] += 10;
361 if (rates[AI_RATE_LUX] > 0) {
362 rates[AI_RATE_LUX] -= 10;
363 } else {
364 rates[AI_RATE_SCI] -= 10;
365 }
366 }
367
368 /* If no minimum value was found for the tax use the maximum tax rate. */
369 rate_tax_min = RATE_VALID(rate_tax_min) ? rate_tax_min : maxrate;
370
371 log_base(LOGLEVEL_TAX, "%s [tax] min=%d balanced=%d", player_name(pplayer),
372 rate_tax_min, rate_tax_balance);
373
374 /* === Science === */
375
376 if (game.info.tech_upkeep_style != TECH_UPKEEP_NONE) {
377 /* Tech upkeep activated. */
378 int tech_upkeep = player_tech_upkeep(pplayer);
379 int bulbs_researched = research->bulbs_researched;
380
381 /* The delta between the estimate and the real value. */
382 delta_sci = (result[AI_RATE_SCI] - tech_upkeep)
383 - pplayer->server.bulbs_last_turn;
384 log_base(LOGLEVEL_TAX, "%s [sci] estimated=%d real=%d (delta=%d)",
385 player_name(pplayer),
386 result[AI_RATE_SCI] - tech_upkeep,
387 pplayer->server.bulbs_last_turn, delta_sci);
388
389 log_base(LOGLEVEL_TAX, "%s [sci] trade=%d bulbs=%d upkeep=%d",
390 player_name(pplayer), trade, research->bulbs_researched,
391 tech_upkeep);
392
393 rates[AI_RATE_TAX] = maxrate; /* Assume we want gold here */
394 rates[AI_RATE_SCI] = MAX(0, 100 - maxrate * 2);
395 rates[AI_RATE_LUX] = (100 - rates[AI_RATE_SCI] - rates[AI_RATE_TAX]);
396
397 /* Now find the minimum science tax with positive bulbs balance
398 * Negative balance is acceptable if we have a lots of bulbs. */
399 while (rates[AI_RATE_SCI] <= maxrate
400 && rates[AI_RATE_TAX] >= 0
401 && rates[AI_RATE_LUX] >= 0) {
402 int balance_sci, balance_sci_min;
403 int i;
404
405 for (i = 0; i < AI_RATE_COUNT; i++) {
406 fc_assert(rates[i] >= 0);
407 rates_tmp[i] = rates[i];
408 }
409 distribute(trade, AI_RATE_COUNT, rates_tmp, result);
410
411 /* Consider the delta between the result and the real value from the
412 * last turn. */
413 balance_sci = (result[AI_RATE_SCI] - tech_upkeep)
414 - delta_sci * PCT_DELTA_SCI / 100;
415 balance_sci_min = -(bulbs_researched
416 / (AI_BULBS_RESERVE_MIN_TURNS + turns_for_rapture));
417 log_base(LOGLEVEL_TAX, "%s [sci] Sci=%d research=%d",
418 player_name(pplayer), rates[AI_RATE_SCI], balance_sci);
419
420 if (!RATE_VALID(rate_sci_min) && balance_sci > balance_sci_min) {
421 /* Just slightly negative, if we can afford that for a while */
422 rate_sci_min = rates[AI_RATE_SCI];
423 }
424
425 if (tech_upkeep == 0 || balance_sci > 0) {
426 /* Ok, got no expenses or positive balance */
427 rate_sci_balance = rates[AI_RATE_SCI];
428
429 /* Done! Break the while loop */
430 break;
431 }
432
433 /* Negative balance. Unacceptable - increase science.*/
434 rates[AI_RATE_SCI] += 10;
435 if (rates[AI_RATE_LUX] > 0) {
436 rates[AI_RATE_LUX] -= 10;
437 } else {
438 rates[AI_RATE_TAX] -= 10;
439 }
440 }
441
442 /* If no minimum value was found for the science use the maximum science
443 * rate. */
444 rate_sci_min = RATE_VALID(rate_sci_min) ? rate_sci_min : maxrate;
445
446 log_base(LOGLEVEL_TAX, "%s [sci] min=%d balanced=%d",
447 player_name(pplayer), rate_sci_min, rate_sci_balance);
448 } else {
449 /* No tech upkeep - minimum science value is 0. */
450 rate_sci_min = 0;
451 }
452
453 /* === Luxury === */
454
455 /* Should (and can) we celebrate? */
456 /* TODO: In the future, we should check if we should
457 * celebrate for other reasons than growth. Currently
458 * this is ignored. Maybe we need ruleset AI hints. */
459 /* TODO: Allow celebrate individual cities? No modpacks use this yet. */
460 if (get_player_bonus(pplayer, EFT_RAPTURE_GROW) > 0
461 && !has_handicap(pplayer, H_AWAY)
462 && 100 > rate_tax_min + rate_sci_min) {
463 celebrate = AI_CELEBRATION_NO;
464
465 /* Set the minimum tax for a positive science and gold balance and use the
466 * remaining trade goods for luxuries (max. luxuries). */
467 rates[AI_RATE_SCI] = rate_sci_min;
468 rates[AI_RATE_TAX] = rate_tax_min;
469 rates[AI_RATE_LUX] = 0;
470
471 rates[AI_RATE_LUX] = MIN(maxrate, rates[AI_RATE_LUX]
472 + RATE_REMAINS(rates));
473 rates[AI_RATE_TAX] = MIN(maxrate, rates[AI_RATE_TAX]
474 + RATE_REMAINS(rates));
475 rates[AI_RATE_SCI] = MIN(maxrate, rates[AI_RATE_SCI]
476 + RATE_REMAINS(rates));
477
478 /* Temporary set the new rates. */
479 pplayer->economic.luxury = rates[AI_RATE_LUX];
480 pplayer->economic.tax = rates[AI_RATE_TAX];
481 pplayer->economic.science = rates[AI_RATE_SCI];
482
483 /* Check if we celebrate - the city state must be restored at the end! */
484 city_list_iterate(pplayer->cities, pcity) {
485 struct cm_result *cmr = cm_result_new(pcity);
486 struct ai_city *city_data = def_ai_city_data(pcity, ait);
487
488 cm_clear_cache(pcity);
489 cm_query_result(pcity, &cmp, cmr, FALSE); /* burn some CPU */
490
491 total_cities++;
492
493 if (cmr->found_a_valid
494 && pcity->surplus[O_FOOD] > 0
495 && city_size_get(pcity) >= game.info.celebratesize
496 && city_can_grow_to(pcity, city_size_get(pcity) + 1)) {
497 city_data->celebrate = TRUE;
498 can_celebrate++;
499 } else {
500 city_data->celebrate = FALSE;
501 }
502 cm_result_destroy(cmr);
503 } city_list_iterate_end;
504
505 /* If more than half our cities can celebrate, go for it! */
506 if (can_celebrate * 2 > total_cities) {
507 celebrate = AI_CELEBRATION_YES;
508 rate_lux_min_celebrate = pplayer->economic.luxury;
509 log_base(LOGLEVEL_TAX, "%s [lux] celebration possible (Sci/Lux/Tax)>="
510 "%d/%d/%d (%d of %d cities)",
511 player_name(pplayer), rate_sci_min, rate_lux_min_celebrate,
512 rate_tax_min, can_celebrate, total_cities);
513 } else {
514 log_base(LOGLEVEL_TAX, "%s [lux] no celebration: only %d of %d cities",
515 player_name(pplayer), can_celebrate, total_cities);
516 }
517 }
518
519 if (celebrate != AI_CELEBRATION_YES) {
520 /* TODO: Calculate a minimum luxury tax rate.
521 * Add general luxury code here. */
522 }
523
524 /* === Set the rates. === */
525
526 /* Reset rates values. */
527 rates[AI_RATE_SCI] = 0;
528 rates[AI_RATE_TAX] = 0;
529 rates[AI_RATE_LUX] = 0;
530
531 /* Now decide that to do ... */
532 if (celebrate == AI_CELEBRATION_YES
533 && rate_tax_min + rate_sci_min + rate_lux_min_celebrate <= 100) {
534 /* Celebration! */
535 rates[AI_RATE_SCI] = rate_sci_min;
536 rates[AI_RATE_TAX] = rate_tax_min;
537 rates[AI_RATE_LUX] = rate_lux_min_celebrate;
538
539 log_base(LOGLEVEL_TAX, "%s [res] celebration! (Sci/Lux/Tax)>=%d/%d/%d",
540 player_name(pplayer), rates[AI_RATE_SCI], rates[AI_RATE_LUX],
541 rates[AI_RATE_TAX]);
542 } else {
543 /* No celebration */
544 celebrate = (celebrate == AI_CELEBRATION_YES) ? AI_CELEBRATION_NO
545 : celebrate;
546
547 if (RATE_VALID(rate_tax_balance)) {
548 if (RATE_VALID(rate_sci_balance)) {
549 if (100 >= rate_tax_balance + rate_sci_balance) {
550 /* A balanced treasury and research. */
551 rates[AI_RATE_SCI] = rate_sci_balance;
552 rates[AI_RATE_TAX] = rate_tax_balance;
553
554 log_base(LOGLEVEL_TAX, "%s [res] balanced! (Sci/Lux/Tax)>=%d/%d/%d",
555 player_name(pplayer), rates[AI_RATE_SCI],
556 rates[AI_RATE_LUX], rates[AI_RATE_TAX]);
557 } else {
558 /* Try to keep all tech and get as much gold as possible. */
559 rates[AI_RATE_SCI] = rate_sci_balance;
560 rates[AI_RATE_TAX] = MIN(maxrate, RATE_REMAINS(rates));
561
562 log_base(LOGLEVEL_TAX, "%s [res] balanced sci! tax? "
563 "(Sci/Lux/Tax)>=%d/%d/%d",
564 player_name(pplayer), rates[AI_RATE_SCI],
565 rates[AI_RATE_LUX], rates[AI_RATE_TAX]);
566 }
567 } else {
568 /* A balanced tax and as much science as possible. */
569 rates[AI_RATE_TAX] = rate_tax_balance;
570 rates[AI_RATE_SCI] = MIN(maxrate, RATE_REMAINS(rates));
571
572 log_base(LOGLEVEL_TAX, "%s [res] balanced tax! sci? "
573 "(Sci/Lux/Tax)>=%d/%d/%d",
574 player_name(pplayer), rates[AI_RATE_SCI],
575 rates[AI_RATE_LUX], rates[AI_RATE_TAX]);
576 }
577 } else if (RATE_VALID(rate_sci_balance)) {
578 /* Try to keep all techs and get as much gold as possible. */
579 rates[AI_RATE_SCI] = rate_sci_balance;
580 rates[AI_RATE_TAX] = MIN(maxrate, RATE_REMAINS(rates));
581
582 log_base(LOGLEVEL_TAX, "%s [res] balanced sci! tax? "
583 "(Sci/Lux/Tax)>=%d/%d/%d",
584 player_name(pplayer), rates[AI_RATE_SCI],
585 rates[AI_RATE_LUX], rates[AI_RATE_TAX]);
586 } else {
587 /* We need more trade to get a positive gold and science balance. */
588 if (!adv_wants_science(pplayer) || dai_on_war_footing(ait, pplayer)) {
589 /* Go for gold (improvements and units) and risk the loss of a
590 * tech. */
591 rates[AI_RATE_TAX] = maxrate;
592 rates[AI_RATE_SCI] = MIN(maxrate, RATE_REMAINS(rates));
593
594 log_base(LOGLEVEL_TAX, "%s [res] risk of tech loss! (Sci/Lux/Tax)>="
595 "%d/%d/%d", player_name(pplayer),
596 rates[AI_RATE_SCI], rates[AI_RATE_LUX],
597 rates[AI_RATE_TAX]);
598 } else {
599 /* Go for science and risk the loss of improvements or units. */
600 rates[AI_RATE_SCI] = MAX(maxrate, rate_sci_min);
601 rates[AI_RATE_TAX] = MIN(maxrate, RATE_REMAINS(rates));
602
603 log_base(LOGLEVEL_TAX, "%s [res] risk of empty treasury! "
604 "(Sci/Lux/Tax)>=%d/%d/%d",
605 player_name(pplayer), rates[AI_RATE_SCI],
606 rates[AI_RATE_LUX], rates[AI_RATE_TAX]);
607 };
608 }
609 }
610
611 /* Put the remaining to tax or science. */
612 if (!adv_wants_science(pplayer)) {
613 rates[AI_RATE_TAX] = MIN(maxrate, rates[AI_RATE_TAX]
614 + RATE_REMAINS(rates));
615 rates[AI_RATE_LUX] = MIN(maxrate, rates[AI_RATE_LUX]
616 + RATE_REMAINS(rates));
617 rates[AI_RATE_SCI] = MIN(maxrate, rates[AI_RATE_SCI]
618 + RATE_REMAINS(rates));
619 } else if (dai_on_war_footing(ait, pplayer)) {
620 rates[AI_RATE_TAX] = MIN(maxrate, rates[AI_RATE_TAX]
621 + RATE_REMAINS(rates));
622 rates[AI_RATE_SCI] = MIN(maxrate, rates[AI_RATE_SCI]
623 + RATE_REMAINS(rates));
624 rates[AI_RATE_LUX] = MIN(maxrate, rates[AI_RATE_LUX]
625 + RATE_REMAINS(rates));
626 } else {
627 rates[AI_RATE_SCI] = MIN(maxrate, rates[AI_RATE_SCI]
628 + RATE_REMAINS(rates));
629 rates[AI_RATE_TAX] = MIN(maxrate, rates[AI_RATE_TAX]
630 + RATE_REMAINS(rates));
631 rates[AI_RATE_LUX] = MIN(maxrate, rates[AI_RATE_LUX]
632 + RATE_REMAINS(rates));
633 }
634
635 /* Check and set the calculated rates. */
636 fc_assert_ret(0 <= rates[AI_RATE_SCI] && rates[AI_RATE_SCI] <= maxrate);
637 fc_assert_ret(0 <= rates[AI_RATE_TAX] && rates[AI_RATE_TAX] <= maxrate);
638 fc_assert_ret(0 <= rates[AI_RATE_LUX] && rates[AI_RATE_LUX] <= maxrate);
639 fc_assert_ret(rates[AI_RATE_SCI] + rates[AI_RATE_TAX] + rates[AI_RATE_LUX]
640 == 100);
641
642 log_base(LOGLEVEL_TAX, "%s [new] (Sci/Lux/Tax)=%d/%d/%d",
643 player_name(pplayer), rates[AI_RATE_SCI], rates[AI_RATE_LUX],
644 rates[AI_RATE_TAX]);
645
646 pplayer->economic.science = rates[AI_RATE_SCI];
647 pplayer->economic.tax = rates[AI_RATE_TAX];
648 pplayer->economic.luxury = rates[AI_RATE_LUX];
649
650 /* === Cleanup === */
651
652 /* Cancel all celebrations from the last turn. */
653 ai->celebrate = FALSE;
654
655 /* Now do celebrate or reset the city states if needed. */
656 if (celebrate == AI_CELEBRATION_YES) {
657 log_base(LOGLEVEL_TAX, "*** %s CELEBRATES! ***", player_name(pplayer));
658
659 /* We do celebrate! */
660 ai->celebrate = TRUE;
661
662 city_list_iterate(pplayer->cities, pcity) {
663 struct cm_result *cmr = cm_result_new(pcity);
664
665 if (def_ai_city_data(pcity, ait)->celebrate) {
666 log_base(LOGLEVEL_TAX, "setting %s to celebrate", city_name_get(pcity));
667 cm_query_result(pcity, &cmp, cmr, FALSE);
668 if (cmr->found_a_valid) {
669 apply_cmresult_to_city(pcity, cmr);
670 city_refresh_from_main_map(pcity, NULL);
671 if (!city_happy(pcity)) {
672 CITY_LOG(LOG_ERROR, pcity, "is NOT happy when it should be!");
673 }
674 } else {
675 CITY_LOG(LOG_ERROR, pcity, "has NO valid state!");
676 }
677 }
678 cm_result_destroy(cmr);
679 } city_list_iterate_end;
680 } else if (celebrate == AI_CELEBRATION_NO) {
681 city_list_iterate(pplayer->cities, pcity) {
682 /* KLUDGE: Must refresh to restore the original values which
683 * were clobbered in cm_query_result(), after the tax rates
684 * were changed. */
685 city_refresh_from_main_map(pcity, NULL);
686 } city_list_iterate_end;
687 }
688
689 send_player_info_c(pplayer, pplayer->connections);
690
691#ifdef DEBUG_TIMERS
692 timer_stop(taxtimer);
693 log_base(LOGLEVEL_TAX, "Tax calculation for %s (player %d) in %.3f "
694 "seconds.", player_name(pplayer),
695 player_index(pplayer), timer_read_seconds(taxtimer));
696 timer_destroy(taxtimer);
697#endif /* DEBUG_TIMERS */
698}
699#undef RATE_NOT_SET
700#undef RATE_VALID
701#undef RATE_REMAINS
702
703/*************************************************************************/
706 static void dai_manage_government(struct ai_type *ait, struct player *pplayer)
707{
708 struct adv_data *adv = adv_data_get(pplayer, NULL);
709
710 if (!pplayer->is_alive || has_handicap(pplayer, H_AWAY)) {
711 return;
712 }
713
714 if (adv->goal.revolution != government_of_player(pplayer)) {
715 dai_government_change(pplayer, adv->goal.revolution); /* change */
716 }
717
718 /* Crank up tech want */
719 if (adv->goal.govt.req == A_UNSET
720 || research_invention_state(research_get(pplayer),
721 adv->goal.govt.req) == TECH_KNOWN) {
722 return; /* already got it! */
723 } else if (adv->goal.govt.val > 0) {
724 /* We have few cities in the beginning, compensate for this to ensure
725 * that we are sufficiently forward-looking. */
726 int want = MAX(adv->goal.govt.val, 100);
727 struct nation_type *pnation = nation_of_player(pplayer);
728 struct ai_plr *plr_data = def_ai_player_data(pplayer, ait);
729
730 if (government_of_player(pplayer) == init_government_of_nation(pnation)) {
731 /* Default government is the crappy one we start in (like Despotism).
732 * We want something better pretty soon! */
733 want += 25 * game.info.turn;
734 }
735 plr_data->tech_want[adv->goal.govt.req] += want;
736 TECH_LOG(ait, LOG_DEBUG, pplayer, advance_by_number(adv->goal.govt.req),
737 "dai_manage_government() + %d for %s",
738 want,
739 government_rule_name(adv->goal.govt.gov));
740 }
741}
742
743/*************************************************************************/
747 void dai_do_first_activities(struct ai_type *ait, struct player *pplayer)
748{
749 TIMING_LOG(AIT_ALL, TIMER_START);
750 dai_assess_danger_player(ait, pplayer, &(wld.map));
751 /* TODO: Make assess_danger save information on what is threatening
752 * us and make dai_manage_units and Co act upon this information, trying
753 * to eliminate the source of danger */
754
755 TIMING_LOG(AIT_UNITS, TIMER_START);
756 dai_manage_units(ait, pplayer);
757 TIMING_LOG(AIT_UNITS, TIMER_STOP);
758 /* STOP. Everything else is at end of turn. */
759
760 TIMING_LOG(AIT_ALL, TIMER_STOP);
761
762 flush_packets(); /* AIs can be such spammers... */
763}
764
765/*************************************************************************/
773 void dai_do_last_activities(struct ai_type *ait, struct player *pplayer)
774{
775 TIMING_LOG(AIT_ALL, TIMER_START);
776 dai_clear_tech_wants(ait, pplayer);
777
778 dai_manage_government(ait, pplayer);
779 dai_adjust_policies(ait, pplayer);
780 TIMING_LOG(AIT_TAXES, TIMER_START);
781 dai_manage_taxes(ait, pplayer);
782 TIMING_LOG(AIT_TAXES, TIMER_STOP);
783 TIMING_LOG(AIT_CITIES, TIMER_START);
784 dai_manage_cities(ait, pplayer);
785 TIMING_LOG(AIT_CITIES, TIMER_STOP);
786 TIMING_LOG(AIT_TECH, TIMER_START);
787 dai_manage_tech(ait, pplayer);
788 TIMING_LOG(AIT_TECH, TIMER_STOP);
789 dai_manage_spaceship(pplayer);
790
791 TIMING_LOG(AIT_ALL, TIMER_STOP);
792}
adv_data_get
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:604
adv_wants_science
bool adv_wants_science(struct player *pplayer)
Definition advdata.c:1095
advdata.h
adv_spaceship_autoplace
bool adv_spaceship_autoplace(struct player *pplayer, struct player_spaceship *ship)
Definition advspace.c:33
advspace.h
advtools.h
celebration
celebration
Definition aihand.c:169
AI_CELEBRATION_NO
@ AI_CELEBRATION_NO
Definition aihand.c:171
AI_CELEBRATION_UNCHECKED
@ AI_CELEBRATION_UNCHECKED
Definition aihand.c:170
AI_CELEBRATION_YES
@ AI_CELEBRATION_YES
Definition aihand.c:172
dai_calc_data
void dai_calc_data(const struct player *pplayer, int *trade, int *expenses, int *income)
Definition aihand.c:117
dai_manage_government
static void dai_manage_government(struct ai_type *ait, struct player *pplayer)
Definition aihand.c:706
RATE_VALID
#define RATE_VALID(_rate)
Definition aihand.c:176
PCT_DELTA_TAX
#define PCT_DELTA_TAX
Definition aihand.c:92
RATE_NOT_SET
#define RATE_NOT_SET
Definition aihand.c:175
LOGLEVEL_TAX
#define LOGLEVEL_TAX
Definition aihand.c:82
dai_do_last_activities
void dai_do_last_activities(struct ai_type *ait, struct player *pplayer)
Definition aihand.c:773
dai_manage_taxes
static void dai_manage_taxes(struct ai_type *ait, struct player *pplayer)
Definition aihand.c:211
RATE_REMAINS
#define RATE_REMAINS(_rates)
Definition aihand.c:178
dai_manage_spaceship
static void dai_manage_spaceship(struct player *pplayer)
Definition aihand.c:98
AI_GOLD_RESERVE_MIN_TURNS
#define AI_GOLD_RESERVE_MIN_TURNS
Definition aihand.c:87
dai_do_first_activities
void dai_do_first_activities(struct ai_type *ait, struct player *pplayer)
Definition aihand.c:747
AI_BULBS_RESERVE_MIN_TURNS
#define AI_BULBS_RESERVE_MIN_TURNS
Definition aihand.c:88
AI_RATE_COUNT
@ AI_RATE_COUNT
Definition aihand.c:166
AI_RATE_TAX
@ AI_RATE_TAX
Definition aihand.c:164
AI_RATE_SCI
@ AI_RATE_SCI
Definition aihand.c:163
AI_RATE_LUX
@ AI_RATE_LUX
Definition aihand.c:165
PCT_DELTA_SCI
#define PCT_DELTA_SCI
Definition aihand.c:93
aihand.h
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1128
city_refresh_from_main_map
void city_refresh_from_main_map(struct city *pcity, bool *workers_map)
Definition city.c:3165
city_can_grow_to
bool city_can_grow_to(const struct city *pcity, int pop_size)
Definition city.c:2004
city_happy
bool city_happy(const struct city *pcity)
Definition city.c:1606
cmp
static int cmp(int v1, int v2)
Definition city.c:324
city.h
city_list_iterate
#define city_list_iterate(citylist, pcity)
Definition city.h:508
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
city_list_iterate_end
#define city_list_iterate_end
Definition city.h:510
citytools.h
apply_cmresult_to_city
void apply_cmresult_to_city(struct city *pcity, const struct cm_result *cmr)
Definition cityturn.c:280
cityturn.h
cm_clear_cache
void cm_clear_cache(struct city *pcity)
Definition cm.c:322
cm_init_parameter
void cm_init_parameter(struct cm_parameter *dest)
Definition cm.c:2180
cm_result_new
struct cm_result * cm_result_new(struct city *pcity)
Definition cm.c:345
cm_result_destroy
void cm_result_destroy(struct cm_result *result)
Definition cm.c:368
cm_query_result
void cm_query_result(struct city *pcity, const struct cm_parameter *param, struct cm_result *result, bool negative_ok)
Definition cm.c:2120
cm.h
incite_cost
char * incite_cost
Definition comments.c:74
dai_manage_cities
void dai_manage_cities(struct ai_type *ait, struct player *pplayer)
Definition daicity.c:850
daicity.h
dai_adjust_policies
void dai_adjust_policies(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:442
daidata.h
dai_on_war_footing
bool dai_on_war_footing(struct ai_type *ait, struct player *pplayer)
Definition daidiplomacy.c:1963
daidiplomacy.h
dailog.h
TECH_LOG
#define TECH_LOG(ait, loglevel, pplayer, padvance, msg,...)
Definition dailog.h:36
dai_assess_danger_player
void dai_assess_danger_player(struct ai_type *ait, struct player *pplayer, const struct civ_map *dmap)
Definition daimilitary.c:630
daimilitary.h
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
dai_clear_tech_wants
void dai_clear_tech_wants(struct ai_type *ait, struct player *pplayer)
Definition daitech.c:611
dai_manage_tech
void dai_manage_tech(struct ai_type *ait, struct player *pplayer)
Definition daitech.c:335
daitech.h
dai_government_change
void dai_government_change(struct player *pplayer, struct government *gov)
Definition daitools.c:1305
dai_gold_reserve
int dai_gold_reserve(struct player *pplayer)
Definition daitools.c:1324
daitools.h
dai_manage_units
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2863
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
distribute
void distribute(int number, unsigned groups, const unsigned *ratios, int *result)
Definition distribute.c:34
distribute.h
get_player_bonus
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
VC_SPACERACE
@ VC_SPACERACE
Definition fc_types.h:1281
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_TRADE
@ O_TRADE
Definition fc_types.h:101
O_GOLD
@ O_GOLD
Definition fc_types.h:101
game
struct civ_game game
Definition game.c:62
wld
struct world wld
Definition game.c:63
game.h
government_of_player
struct government * government_of_player(const struct player *pplayer)
Definition government.c:114
government_rule_name
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
government.h
handle_spaceship_launch
void handle_spaceship_launch(struct player *pplayer)
Definition spacerace.c:167
has_handicap
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
handicaps.h
H_RATES
@ H_RATES
Definition handicaps.h:23
H_AWAY
@ H_AWAY
Definition handicaps.h:19
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
log_base
#define log_base(level, message,...)
Definition log.h:94
LOG_ERROR
@ LOG_ERROR
Definition log.h:30
LOG_DEBUG
@ LOG_DEBUG
Definition log.h:34
map.h
nation_of_player
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
init_government_of_nation
struct government * init_government_of_nation(const struct nation_type *pnation)
Definition nation.c:659
nation.h
packets.h
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:895
player_index
int player_index(const struct player *pplayer)
Definition player.c:829
player.h
send_player_info_c
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1146
plrhand.h
player_tech_upkeep
int player_tech_upkeep(const struct player *pplayer)
Definition research.c:1058
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:128
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
research.h
flush_packets
void flush_packets(void)
Definition sernet.c:376
sernet.h
shared.h
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
MIN
#define MIN(x, y)
Definition shared.h:55
FC_INFINITY
#define FC_INFINITY
Definition shared.h:36
MAX
#define MAX(x, y)
Definition shared.h:54
spacerace.h
NUM_SS_MODULES
#define NUM_SS_MODULES
Definition spaceship.h:89
NUM_SS_COMPONENTS
#define NUM_SS_COMPONENTS
Definition spaceship.h:88
NUM_SS_STRUCTURALS
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
SSHIP_STARTED
@ SSHIP_STARTED
Definition spaceship.h:84
srv_log.h
CITY_LOG
#define CITY_LOG(loglevel, pcity, msg,...)
Definition srv_log.h:83
AIT_TAXES
@ AIT_TAXES
Definition srv_log.h:48
AIT_UNITS
@ AIT_UNITS
Definition srv_log.h:43
AIT_CITIES
@ AIT_CITIES
Definition srv_log.h:49
AIT_TECH
@ AIT_TECH
Definition srv_log.h:53
AIT_ALL
@ AIT_ALL
Definition srv_log.h:41
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::req
int req
Definition advdata.h:133
adv_data::val
adv_want val
Definition advdata.h:132
adv_data::revolution
struct government * revolution
Definition advdata.h:135
adv_data::celebrate
bool celebrate
Definition advdata.h:142
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
ai_city
Definition daicity.h:34
ai_city::celebrate
bool celebrate
Definition daicity.h:57
ai_plr
Definition daidata.h:71
ai_type
Definition ai.h:50
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::government_during_revolution
struct government * government_during_revolution
Definition game.h:94
cm_parameter
Definition cm.h:40
cm_result
Definition cm.h:52
nation_type
Definition nation.h:98
packet_game_info::celebratesize
int celebratesize
Definition packets_gen.h:143
packet_game_info::gold_upkeep_style
enum gold_upkeep_style gold_upkeep_style
Definition packets_gen.h:172
packet_game_info::tech_upkeep_style
enum tech_upkeep_style tech_upkeep_style
Definition packets_gen.h:235
packet_game_info::changable_tax
bool changable_tax
Definition packets_gen.h:144
packet_game_info::rapturedelay
int rapturedelay
Definition packets_gen.h:222
packet_game_info::turn
int turn
Definition packets_gen.h:247
player_economic::luxury
int luxury
Definition player.h:66
player_economic::science
int science
Definition player.h:65
player_economic::tax
int tax
Definition player.h:64
player_economic::gold
int gold
Definition player.h:63
player_spaceship::modules
int modules
Definition spaceship.h:98
player_spaceship::components
int components
Definition spaceship.h:97
player_spaceship::state
enum spaceship_state state
Definition spaceship.h:108
player_spaceship::structurals
int structurals
Definition spaceship.h:96
player
Definition player.h:249
player::cities
struct city_list * cities
Definition player.h:281
player::bulbs_last_turn
int bulbs_last_turn
Definition player.h:351
player::units
struct unit_list * units
Definition player.h:282
player::connections
struct conn_list * connections
Definition player.h:298
player::is_alive
bool is_alive
Definition player.h:268
player::economic
struct player_economic economic
Definition player.h:284
player::spaceship
struct player_spaceship spaceship
Definition player.h:286
player::server
struct player::@70::@72 server
research
Definition research.h:39
research::bulbs_researched
int bulbs_researched
Definition research.h:53
timer
Definition timing.c:81
unit::upkeep
int upkeep[O_LAST]
Definition unit.h:150
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
advance_by_number
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
A_UNSET
#define A_UNSET
Definition tech.h:48
timer_destroy
void timer_destroy(struct timer *t)
Definition timing.c:208
timer_start
void timer_start(struct timer *t)
Definition timing.c:264
timer_stop
void timer_stop(struct timer *t)
Definition timing.c:308
timer_new
struct timer * timer_new(enum timer_timetype type, enum timer_use use, const char *name)
Definition timing.c:160
timer_read_seconds
double timer_read_seconds(struct timer *t)
Definition timing.c:384
timing.h
TIMER_DEBUG
#define TIMER_DEBUG
Definition timing.h:61
TIMER_CPU
@ TIMER_CPU
Definition timing.h:41
unit.h
unithand.h
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
victory_enabled
bool victory_enabled(enum victory_condition_type victory)
Definition victory.c:26
victory.h