Freeciv-3.1: /fast/freeciv/nightly/S3_1/ai/default/aihand.c Source File

Freeciv-3.1

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