Comment fix: OS is not excluded from permissive.
[freeciv.git] / common / aicore / citymap.c
blob06be7fb295f41b16fa8f5f11ded2816322838824
1 /***********************************************************************
2 Freeciv - Copyright (C) 2003 - Per I. Mathisen
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 #include <stdio.h>
19 #include <string.h>
21 /* utility */
22 #include "log.h"
23 #include "mem.h"
24 #include "support.h"
26 /* common */
27 #include "city.h"
28 #include "game.h"
29 #include "map.h"
30 #include "unit.h"
31 #include "unitlist.h"
32 #include "unittype.h"
34 #include "citymap.h"
36 /* CITYMAP - reserve space for cities
38 * The citymap is a large int double array that corresponds to
39 * the freeciv main map. For each tile, it stores three different
40 * and exclusive values in a single int: A positive int tells you
41 * how many cities can use this tile (a crowdedness inidicator). A
42 * value of zero indicates that the tile is presently unused and
43 * available. A negative value means that this tile is occupied
44 * and reserved by some city or unit: in this case the value gives
45 * the negative of the ID of the city or unit that has reserved the
46 * tile.
48 * Code that uses the citymap should modify its behaviour based on
49 * positive values encountered, and never attempt to steal a tile
50 * which has a negative value.
53 static int *citymap = NULL;
55 #define log_citymap log_debug
57 /**************************************************************************
58 Initialize citymap by reserving worked tiles and establishing the
59 crowdedness of (virtual) cities.
60 **************************************************************************/
61 void citymap_turn_init(struct player *pplayer)
63 /* The citymap is reinitialized at the start of ever turn. This includes
64 * a call to realloc, which only really matters if this is the first turn
65 * of the game (but it's easier than a separate function to do this). */
66 citymap = fc_realloc(citymap, MAP_INDEX_SIZE * sizeof(*citymap));
67 memset(citymap, 0, MAP_INDEX_SIZE * sizeof(*citymap));
69 players_iterate(pother) {
70 city_list_iterate(pother->cities, pcity) {
71 struct tile *pcenter = city_tile(pcity);
73 /* reserve at least the default (squared) city radius */
74 city_tile_iterate(MAX(city_map_radius_sq_get(pcity),
75 CITY_MAP_DEFAULT_RADIUS_SQ),
76 pcenter, ptile) {
77 struct city *pwork = tile_worked(ptile);
79 if (NULL != pwork) {
80 citymap[tile_index(ptile)] = -(pwork->id);
81 } else {
82 citymap[tile_index(ptile)]++;
84 } city_tile_iterate_end;
85 } city_list_iterate_end;
86 } players_iterate_end;
88 unit_list_iterate(pplayer->units, punit) {
89 if (unit_is_cityfounder(punit)
90 && punit->server.adv->task == AUT_BUILD_CITY) {
92 /* use default (squared) city radius */
93 city_tile_iterate(CITY_MAP_DEFAULT_RADIUS_SQ, punit->goto_tile,
94 ptile) {
95 if (citymap[tile_index(ptile)] >= 0) {
96 citymap[tile_index(ptile)]++;
98 } city_tile_iterate_end;
100 citymap[tile_index(punit->goto_tile)] = -(punit->id);
102 } unit_list_iterate_end;
105 /**************************************************************************
106 Free resources allocated for citymap.
107 **************************************************************************/
108 void citymap_free(void)
110 if (citymap != NULL) {
111 FC_FREE(citymap);
115 /**************************************************************************
116 This function reserves a single tile for a (possibly virtual) city with
117 a settler's or a city's id. Then it 'crowds' tiles that this city can
118 use to make them less attractive to other cities we may consider making.
119 **************************************************************************/
120 void citymap_reserve_city_spot(struct tile *ptile, int id)
122 #ifdef FREECIV_DEBUG
123 log_citymap("id %d reserving (%d, %d), was %d",
124 id, TILE_XY(ptile), citymap[tile_index(ptile)]);
125 fc_assert_ret(0 <= citymap[tile_index(ptile)]);
126 #endif /* FREECIV_DEBUG */
128 /* Tiles will now be "reserved" by actual workers, so free excess
129 * reservations. Also mark tiles for city overlapping, or 'crowding'.
130 * Uses the default city map size / squared city radius. */
131 city_tile_iterate(CITY_MAP_DEFAULT_RADIUS_SQ, ptile, ptile1) {
132 if (citymap[tile_index(ptile1)] == -id) {
133 citymap[tile_index(ptile1)] = 0;
135 if (citymap[tile_index(ptile1)] >= 0) {
136 citymap[tile_index(ptile1)]++;
138 } city_tile_iterate_end;
140 citymap[tile_index(ptile)] = -(id);
143 /**************************************************************************
144 Reverse any reservations we have made in the surrounding area.
145 **************************************************************************/
146 void citymap_free_city_spot(struct tile *ptile, int id)
148 city_tile_iterate(CITY_MAP_DEFAULT_RADIUS_SQ, ptile, ptile1) {
149 if (citymap[tile_index(ptile1)] == -(id)) {
150 citymap[tile_index(ptile1)] = 0;
151 } else if (citymap[tile_index(ptile1)] > 0) {
152 citymap[tile_index(ptile1)]--;
154 } city_tile_iterate_end;
157 /**************************************************************************
158 Reserve additional tiles as desired (eg I would reserve best available
159 food tile in addition to adjacent tiles)
160 **************************************************************************/
161 void citymap_reserve_tile(struct tile *ptile, int id)
163 #ifdef FREECIV_DEBUG
164 fc_assert_ret(!citymap_is_reserved(ptile));
165 #endif
167 citymap[tile_index(ptile)] = -id;
170 /**************************************************************************
171 Returns a positive value if within a city radius, which is 1 x number of
172 cities you are within the radius of, or zero or less if not. A negative
173 value means this tile is reserved by a city and should not be taken.
174 **************************************************************************/
175 int citymap_read(struct tile *ptile)
177 return citymap[tile_index(ptile)];
180 /**************************************************************************
181 A tile is reserved if it contains a city or unit id, or a worker is
182 assigned to it.
183 **************************************************************************/
184 bool citymap_is_reserved(struct tile *ptile)
186 if (NULL != tile_worked(ptile) /*|| tile_city(ptile)*/) {
187 return TRUE;
189 return (citymap[tile_index(ptile)] < 0);