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