Move tools_fc_interface.[c|h] to tools/shared.
[freeciv.git] / common / aicore / aisupport.c
blob8fa90d08a563f8a4bffc2c9a8b5c70df92437e7d
1 /**********************************************************************
2 Freeciv - Copyright (C) 2003 - The Freeciv Project
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utility */
19 #include "log.h"
20 #include "shared.h"
21 #include "support.h"
23 /* common */
24 #include "city.h"
25 #include "game.h"
26 #include "map.h"
27 #include "player.h"
28 #include "spaceship.h"
29 #include "tech.h"
30 #include "unitlist.h"
31 #include "victory.h"
33 #include "aisupport.h"
35 /**********************************************************************
36 Find who is leading the space race. Returns NULL if nobody is.
37 ***********************************************************************/
38 struct player *player_leading_spacerace(void)
40 struct player *best = NULL;
41 int best_arrival = FC_INFINITY;
42 enum spaceship_state best_state = SSHIP_NONE;
44 if (!victory_enabled(VC_SPACERACE)) {
45 return NULL;
48 players_iterate_alive(pplayer) {
49 struct player_spaceship *ship = &pplayer->spaceship;
50 int arrival = (int) ship->travel_time + ship->launch_year;
52 if (is_barbarian(pplayer) || ship->state == SSHIP_NONE) {
53 continue;
56 if (ship->state != SSHIP_LAUNCHED
57 && ship->state > best_state) {
58 best_state = ship->state;
59 best = pplayer;
60 } else if (ship->state == SSHIP_LAUNCHED
61 && arrival < best_arrival) {
62 best_state = ship->state;
63 best_arrival = arrival;
64 best = pplayer;
66 } players_iterate_alive_end;
68 return best;
71 /**********************************************************************
72 Calculate average distances to other players. We calculate the
73 average distance from all of our cities to the closest enemy city.
74 ***********************************************************************/
75 int player_distance_to_player(struct player *pplayer, struct player *target)
77 int cities = 0;
78 int dists = 0;
80 if (pplayer == target
81 || !target->is_alive
82 || !pplayer->is_alive
83 || city_list_size(pplayer->cities) == 0
84 || city_list_size(target->cities) == 0) {
85 return 1;
88 /* For all our cities, find the closest distance to an enemy city. */
89 city_list_iterate(pplayer->cities, pcity) {
90 int min_dist = FC_INFINITY;
92 city_list_iterate(target->cities, c2) {
93 int dist = real_map_distance(c2->tile, pcity->tile);
95 if (min_dist > dist) {
96 min_dist = dist;
98 } city_list_iterate_end;
99 dists += min_dist;
100 cities++;
101 } city_list_iterate_end;
103 return MAX(dists / cities, 1);
106 /**********************************************************************
107 Rough calculation of the worth of pcity in gold.
108 ***********************************************************************/
109 int city_gold_worth(struct city *pcity)
111 struct player *pplayer = city_owner(pcity);
112 int worth = 0, i;
113 struct unit_type *u = NULL;
115 if (!game.scenario.prevent_new_cities) {
116 u = best_role_unit_for_player(city_owner(pcity),
117 action_id_get_role(ACTION_FOUND_CITY));
120 if (u != NULL) {
121 worth += utype_buy_gold_cost(u, 0); /* cost of settler */
123 for (i = 1; i < city_size_get(pcity); i++) {
124 worth += city_granary_size(i); /* cost of growing city */
126 output_type_iterate(o) {
127 worth += pcity->prod[o] * 10;
128 } output_type_iterate_end;
129 unit_list_iterate(pcity->units_supported, punit) {
130 if (same_pos(unit_tile(punit), pcity->tile)) {
131 struct unit_type *punittype = unit_type_get(punit)->obsoleted_by;
133 if (punittype && can_city_build_unit_direct(pcity, punittype)) {
134 worth += unit_disband_shields(punit); /* obsolete, candidate for disbanding */
135 } else {
136 worth += unit_build_shield_cost(punit); /* good stuff */
139 } unit_list_iterate_end;
140 city_built_iterate(pcity, pimprove) {
141 if (improvement_obsolete(pplayer, pimprove, pcity)) {
142 worth += impr_sell_gold(pimprove); /* obsolete, candidate for selling */
143 } else if (!is_wonder(pimprove)) {
144 worth += impr_build_shield_cost(pimprove) * 2; /* Buy cost, with nonzero shield amount */
145 } else {
146 worth += impr_build_shield_cost(pimprove) * 4;
148 } city_built_iterate_end;
149 if (city_unhappy(pcity)) {
150 worth *= 0.75;
152 return worth;