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)
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 ***********************************************************************/
15 #include <fc_config.h>
28 #include "spaceship.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
)) {
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
) {
56 if (ship
->state
!= SSHIP_LAUNCHED
57 && ship
->state
> best_state
) {
58 best_state
= ship
->state
;
60 } else if (ship
->state
== SSHIP_LAUNCHED
61 && arrival
< best_arrival
) {
62 best_state
= ship
->state
;
63 best_arrival
= arrival
;
66 } players_iterate_alive_end
;
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
)
83 || city_list_size(pplayer
->cities
) == 0
84 || city_list_size(target
->cities
) == 0) {
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
) {
98 } city_list_iterate_end
;
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
);
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
));
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 */
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 */
146 worth
+= impr_build_shield_cost(pimprove
) * 4;
148 } city_built_iterate_end
;
149 if (city_unhappy(pcity
)) {