[Freeciv-Dev] Re: (PR#9956) PATCH new rand_map_pos_condition tool for ma
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] Re: (PR#9956) PATCH new rand_map_pos_condition tool for mapgen code |
From: |
"Marcelo Burda" <mburda@xxxxxxxxx> |
Date: |
Mon, 6 Sep 2004 09:58:21 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9956 >
Le lun 06/09/2004 à 16:57, Mateusz Stefek a écrit :
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=9956 >
>
> forever should be removed from make_swamps().
> --
> mateusz
>
Minor fixes
spetially i rename it as rand_map_pos_characteristic
Marcelo
Les fichiers freeciv/manual/civmanual et freeciv_/manual/civmanual sont
diff�©rents.
diff -ruN -Xfreeciv/diff_ignore freeciv/server/mapgen.c freeciv_/server/mapgen.c
--- freeciv/server/mapgen.c 2004-09-04 11:59:41.000000000 +0200
+++ freeciv_/server/mapgen.c 2004-09-06 16:57:51.906984144 +0200
@@ -99,19 +99,33 @@
};
static struct isledata *islands;
-/* this is the maximal temperature at equators returned by map_latitude */
+/* this is the maximal temperature at equators returned by map_temperature */
#define MAX_TEMP 1000
/* An estimate of the linear (1-dimensional) size of the map. */
#define SQSIZE MAX(1, sqrt(map.xsize * map.ysize / 1000))
+/* define the 5 region of a Earth like map
+ =========================================================
+ 0-COLD_LV cold region:
+ COLD_LV-TREOPICAL_LV temperate wet region:
+ TROPICAL_LV-MAX_TEMP tropical wet region:
+
+ and a dry region, this last one can ovelap others
+ DRY_MIN_LEVEL- DRY_MAX_LEVEL
+ */
+#define COLD_LEVEL (10 * MAX_TEMP / 100)
+#define TROPICAL_LEVEL (70 * MAX_TEMP / 100)
+#define DRY_MIN_LEVEL (65 * MAX_TEMP / 100)
+#define DRY_MAX_LEVEL (80 * MAX_TEMP / 100)
+
/* used to create the poles and for separating them. In a
* mercator projection map we don't want the poles to be too big. */
#define ICE_BASE_LEVEL \
((!topo_has_flag(TF_WRAPX) || !topo_has_flag(TF_WRAPY)) \
/* 5% for little maps; 2% for big ones */ \
? MAX_TEMP * (3 + 2 * SQSIZE) / (100 * SQSIZE) \
- : 5 * MAX_TEMP / 100 /* 5% for all maps */)
+ : COLD_LEVEL / 2 /* for all maps */)
/****************************************************************************
Used to initialize an array 'a' of size 'size' with value 'val' in each
@@ -127,7 +141,8 @@
}
/****************************************************************************
- It can be used to many things, placed terrains on lands, placed huts, etc
+ Map that contains, according to circumstances, information on whether
+ we have already placed terrain (special, hut) here.
****************************************************************************/
static bool *placed_map;
@@ -136,14 +151,15 @@
****************************************************************************/
static void create_placed_map(void)
{
- placed_map = fc_malloc (sizeof(bool) * MAX_MAP_INDEX);
- INITIALIZE_ARRAY(placed_map, MAX_MAP_INDEX, FALSE );
+ assert(placed_map == NULL);
+ placed_map = fc_malloc (sizeof(bool) * MAX_MAP_INDEX);
+ INITIALIZE_ARRAY(placed_map, MAX_MAP_INDEX, FALSE );
}
/****************************************************************************
Free the pmap
****************************************************************************/
-static void remove_placed_map(void)
+static void destroy_placed_map(void)
{
free(placed_map);
placed_map = NULL;
@@ -286,42 +302,145 @@
- 0.5 * (x * x * x + y * y * y)
+ 1.5 * (x * x + y * y));
}
+/****************************************************************************
+ * Conditions
+ ****************************************************************************/
+/* WETNESS */
+/*
+ * conditions for allow a dessert to be placed
+ */
+#define map_pos_is_dry(x, y) ((map_temperature((x), (y)) <= DRY_MAX_LEVEL) &&\
+ (map_temperature((x), (y)) > DRY_MIN_LEVEL) && \
+ (count_ocean_near_tile((x),(y),FALSE) <= 2))
+#define wetness_c enum wconsitions
+enum wconsitions { WC_ALL = 1, WC_DRY, WC_NDRY };
+/* TEMPERATURE */
+/*
+ * conditions for allow a jungle to be placed
+ */
+#define map_pos_is_tropical(x, y) (map_temperature((x), (y)) > TROPICAL_LEVEL)
+
+/*
+ * conditions for allow a arctic to be placed
+ */
+#define map_pos_is_frizzed(x, y) \
+ (map_temperature((x), (y)) <= 2 * ICE_BASE_LEVEL)
+/*
+ * conditions for allow a tundra to be placed
+ */
+#define map_pos_is_cold(x, y) (map_temperature((x), (y)) <= COLD_LEVEL && \
+ !map_pos_is_frizzed((x), (y)))
+/*
+ * used by generator 2-4
+ */
+#define map_pos_is_cold_or_frizzed(x, y) \
+ (map_temperature((x), (y)) <= COLD_LEVEL)
+
+#define temperature_c enum tconsitions
+enum tconsitions { TC_ALL = 100, TC_FRIZZED, TC_NFRIZZED, TC_COLD,
+ TC_TROPICAL, TC_NTROPICAL};
+/* MISCELANEOUS */
+/*
+ * conditions for allow a swamp to be placed
+ * hmap_low_level is for speed up it
+ */
+static int hmap_low_level = 0;
+#define ini_hmap_low_level \
+{ \
+hmap_low_level = (2 * map.swampsize * \
+ (hmap_max_level - hmap_shore_level)) / 100 + hmap_shore_level; \
+}
+#define map_pos_is_low(x, y) ( hmap((x), (y)) < hmap_low_level )
+#define miscellaneous_c enum consitions
+enum consitions { MC_NONE = 200, MC_LOW, MC_NLOW };
+
+/***************************************
+ * these functions test for conditions
+ ****************************************/
+static bool test_wetness(int x, int y, wetness_c c)
+{
+ switch(c) {
+ case WC_ALL:
+ return TRUE;
+ case WC_DRY:
+ return map_pos_is_dry(x, y);
+ case WC_NDRY:
+ return !map_pos_is_dry(x, y);
+ default:
+ assert(0);
+ }
+}
+static bool test_temperature(int x, int y, temperature_c c)
+{
+ switch(c) {
+ case TC_ALL:
+ return TRUE;
+ case TC_FRIZZED:
+ return map_pos_is_frizzed(x, y);
+ case TC_NFRIZZED:
+ return !map_pos_is_cold(x, y);
+ case TC_COLD:
+ return map_pos_is_cold(x, y);
+ case TC_TROPICAL:
+ return map_pos_is_tropical(x, y);
+ case TC_NTROPICAL:
+ return !map_pos_is_tropical(x, y);
+ default:
+ assert(0);
+ }
+}
+static bool test_miscellaneous(int x, int y, miscellaneous_c c)
+{
+ switch(c) {
+ case MC_NONE:
+ return TRUE;
+ case MC_LOW:
+ return map_pos_is_low(x, y);
+ case MC_NLOW:
+ return !map_pos_is_low(x, y);
+ default:
+ assert(0);
+ }
+}
struct DataFilter {
- int T_min, T_max;
+ wetness_c wc;
+ temperature_c tc;
+ miscellaneous_c mc;
+
};
/****************************************************************************
A filter function to be passed to rand_map_pos_filtered(). See
- rand_map_pos_temperature for more explanation.
+ rand_map_pos_condition for more explanation.
****************************************************************************/
-static bool temperature_filter(int map_x, int map_y, void *data)
+static bool condition_filter(int map_x, int map_y, void *data)
{
struct DataFilter *filter = data;
- const int T = map_temperature(map_x, map_y);
- return (T >= filter->T_min) && (T <= filter->T_max)
- && not_placed(map_x, map_y) ;
+ return not_placed(map_x, map_y)
+ && test_temperature(map_x, map_y, filter->tc)
+ && test_wetness(map_x, map_y, filter->wc)
+ && test_miscellaneous(map_x, map_y, filter->mc) ;
}
/****************************************************************************
- Return random map coordinates which have temperature within the selected
- range and which are not yet placed on pmap. Returns FALSE if there is no
- such position.
+ Return random map coordinates which have some conditions and which are
+ not yet placed on pmap.
+ Returns FALSE if there is no such position.
****************************************************************************/
-static bool rand_map_pos_temperature(int *map_x, int *map_y,
- int T_min, int T_max)
+static bool rand_map_pos_characteristic(int *map_x, int *map_y,
+ wetness_c wc,
+ temperature_c tc,
+ miscellaneous_c mc )
{
struct DataFilter filter;
- /* We could short-circuit the logic here (for instance, for non-temperate
- * requests on a temperate map). However this is unnecessary and isn't
- * extensible. So instead we just go straight to the rand_map_pos_filtered
- * call. */
-
- filter.T_min = T_min;
- filter.T_max = T_max;
- return rand_map_pos_filtered(map_x, map_y, &filter, temperature_filter);
+
+ filter.wc = wc;
+ filter.tc = tc;
+ filter.mc = mc;
+ return rand_map_pos_filtered(map_x, map_y, &filter, condition_filter);
}
/****************************************************************************
@@ -527,8 +646,8 @@
do {
/* Place one forest clump anywhere. */
- if (rand_map_pos_temperature(&x, &y,
- MAX_TEMP / 10, MAX_TEMP)) {
+ if (rand_map_pos_characteristic(&x, &y, WC_ALL, TC_NFRIZZED, MC_NONE))
+ {
make_forest(x, y, hmap(x, y), 25);
} else {
/* If rand_map_pos_temperature returns FALSE we may as well stop
@@ -537,14 +656,12 @@
}
/* Now add another tropical forest clump (70-100% temperature). */
- if (rand_map_pos_temperature(&x, &y,
- 7 *MAX_TEMP / 10, MAX_TEMP)) {
+ if (rand_map_pos_characteristic(&x, &y, WC_ALL, TC_TROPICAL, MC_NONE)) {
make_forest(x, y, hmap(x, y), 25);
}
/* And add a cold forest clump (10%-30% temperature). */
- if (rand_map_pos_temperature(&x, &y,
- 1 * MAX_TEMP / 10, 3 * MAX_TEMP / 10)) {
+ if (rand_map_pos_characteristic(&x, &y, WC_ALL, TC_COLD, MC_NONE)) {
make_forest(x, y, hmap(x, y), 25);
}
} while (forests < forestsize);
@@ -559,32 +676,23 @@
static void make_swamps(void)
{
int x, y, swamps;
- int forever = 0;
const int swamps_to_be_placed
= MAX_MAP_INDEX * map.swampsize * map.landpercent / 10000;
- const int hmap_swamp_level = ((hmap_max_level - hmap_shore_level)
- * 2 * map.swampsize) / 100 + hmap_shore_level;
for (swamps = 0; swamps < swamps_to_be_placed; ) {
- forever++;
- if (forever > 1000) {
+ if (!rand_map_pos_characteristic(&x, &y, WC_NDRY, TC_NFRIZZED, MC_LOW)) {
return;
}
- rand_map_pos(&x, &y);
- if (not_placed(x, y)
- && hmap(x, y) < hmap_swamp_level) {
- map_set_terrain(x, y, T_SWAMP);
- map_set_placed(x, y);
- cardinal_adjc_iterate(x, y, x1, y1) {
- if (myrand(10) > 5 && not_placed(x1, y1)) {
- map_set_terrain(x1, y1, T_SWAMP);
- map_set_placed(x1, y1);
- swamps++;
- }
- } cardinal_adjc_iterate_end;
- swamps++;
- forever = 0;
- }
+ map_set_terrain(x, y, T_SWAMP);
+ map_set_placed(x, y);
+ cardinal_adjc_iterate(x, y, x1, y1) {
+ if (myrand(10) > 5 && not_placed(x1, y1) && map_pos_is_low(x1, y1)) {
+ map_set_terrain(x1, y1, T_SWAMP);
+ map_set_placed(x1, y1);
+ swamps++;
+ }
+ } cardinal_adjc_iterate_end;
+ swamps++;
}
}
@@ -603,8 +711,7 @@
/* Choose a random coordinate between 20 and 30 degrees north/south
* (deserts tend to be between 15 and 35; make_desert will expand
* them). */
- if (rand_map_pos_temperature(&x, &y,
- 65 * MAX_TEMP / 100, 80 * MAX_TEMP / 100)){
+ if (rand_map_pos_characteristic(&x, &y, WC_DRY, TC_NFRIZZED, MC_NONE)) {
make_desert(x, y, hmap(x, y), 50, map_temperature(x, y));
i--;
} else {
@@ -975,13 +1082,14 @@
Is needed to stop a potentially infinite loop. */
int iteration_counter = 0;
+ create_placed_map(); /* needed bu rand_map_characteristic but no used */
river_map = fc_malloc(sizeof(int) * map.xsize * map.ysize);
/* The main loop in this function. */
while (current_riverlength < desirable_riverlength
&& iteration_counter < RIVERS_MAXTRIES) {
- rand_map_pos(&x, &y);
+ rand_map_pos_characteristic(&x, &y, WC_NDRY, TC_NFRIZZED, MC_NLOW);
/* Check if it is suitable to start a river on the current tile.
*/
@@ -1062,6 +1170,7 @@
current_riverlength, desirable_riverlength, iteration_counter);
} /* end while; */
free(river_map);
+ destroy_placed_map();
river_map = NULL;
}
@@ -1173,6 +1282,7 @@
adjust_hmap();
normalize_hmap_poles();
hmap_shore_level = (hmap_max_level * (100 - map.landpercent)) / 100;
+ ini_hmap_low_level;
whole_map_iterate(x, y) {
map_set_terrain(x, y, T_UNKNOWN); /* set as oceans count is used */
if (hmap(x, y) < hmap_shore_level) {
@@ -1191,8 +1301,8 @@
make_deserts();
make_plains();
make_fair();
+ destroy_placed_map();
make_rivers();
- remove_placed_map();
assign_continent_numbers();
}
@@ -1820,8 +1930,7 @@
/* Add a hut. But not on a polar area, on an ocean, or too close to
* another hut. */
- if (rand_map_pos_temperature(&x, &y,
- 2 * ICE_BASE_LEVEL, MAX_TEMP)) {
+ if (rand_map_pos_characteristic(&x, &y, WC_ALL, TC_NFRIZZED, MC_NONE)) {
if (is_ocean(map_get_terrain(x, y))) {
map_set_placed(x, y); /* not good for a hut */
} else {
@@ -1834,7 +1943,7 @@
}
}
}
- remove_placed_map();
+ destroy_placed_map();
}
/****************************************************************************
@@ -1895,11 +2004,6 @@
long int totalmass;
};
-static bool map_pos_is_cold(int x, int y)
-{
- return map_temperature(x, y) <= 2 * MAX_TEMP/ 10;
-}
-
/**************************************************************************
Returns a random position in the rectangle denoted by the given state.
**************************************************************************/
@@ -1967,7 +2071,7 @@
|| is_terrain_near_tile(x,y,cold1)
)
&&( !is_cardinally_adj_to_ocean(x, y) || myrand(100) < coast )) {
- if (map_pos_is_cold(x, y)) {
+ if (map_pos_is_cold_or_frizzed(x, y)) {
map_set_terrain(x, y, (myrand(cold0_weight
+ cold1_weight) < cold0_weight)
? cold0 : cold1);
@@ -2436,7 +2540,7 @@
}
make_plains();
- remove_placed_map();
+ destroy_placed_map();
free(height_map);
height_map = NULL;
@@ -2524,7 +2628,7 @@
}
make_plains();
- remove_placed_map();
+ destroy_placed_map();
free(height_map);
height_map = NULL;
@@ -2592,7 +2696,7 @@
make_island(10 * pstate->totalmass / totalweight, 0, pstate, DMSIS);
}
make_plains();
- remove_placed_map();
+ destroy_placed_map();
free(height_map);
height_map = NULL;
|
|