[Freeciv-Dev] (PR#9956) PATCH new rand_map_pos_condition tool for mapgen
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] (PR#9956) PATCH new rand_map_pos_condition tool for mapgen code |
From: |
"Marcelo Burda" <mburda@xxxxxxxxx> |
Date: |
Sun, 5 Sep 2004 11:16:21 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9956 >
The rand_map_pos_temperature is rm and a new rand_map_pos_condition is
create
new code search randomly pos with some good defined conditions, no
numericals parameters!
the conditions are coded in a naive form, laters others patch will
modifi it.
there are from 3 types, temperature, wetness and miscelaneous, later a
condtions relief can be added
Some clean ups,indendts, assert and comments fix was included. specially
remove_placed_map was renamed destroy_placed_map. this is not related to
the rand_map_pos_condition code, but is ok i think.
Marcelo
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-05 18:08:52.308905352 +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,134 @@
- 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)))
+
+#define temperature_c enum tconsitions
+enum tconsitions { TC_ALL = 100, TC_FRIZZED, TC_NFRIZZED, TC_COLD,
+ TC_TROPICAL, TC_NTROPICAL};
+/* OTHERS */
+/*
+ * conditions for allow a swamp to be placed
+ */
+#define map_pos_is_low(x, y) ((hmap((x), (y)) - hmap_shore_level) * 100 \
+ <2 * map.swampsize * (hmap_mountain_level - hmap_shore_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_condition(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 +635,7 @@
do {
/* Place one forest clump anywhere. */
- if (rand_map_pos_temperature(&x, &y,
- MAX_TEMP / 10, MAX_TEMP)) {
+ if (rand_map_pos_condition(&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 +644,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_condition(&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_condition(&x, &y, WC_ALL, TC_COLD, MC_NONE)) {
make_forest(x, y, hmap(x, y), 25);
}
} while (forests < forestsize);
@@ -562,29 +667,26 @@
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) {
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;
+ if(!rand_map_pos_condition(&x, &y, WC_NDRY, TC_NFRIZZED, MC_LOW)) {
+ return;
}
+ 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;
}
}
@@ -603,8 +705,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_condition(&x, &y, WC_DRY, TC_NFRIZZED, MC_NONE)) {
make_desert(x, y, hmap(x, y), 50, map_temperature(x, y));
i--;
} else {
@@ -975,13 +1076,14 @@
Is needed to stop a potentially infinite loop. */
int iteration_counter = 0;
+ create_placed_map(); /* needed bu rand_map_condition 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_condition(&x, &y, WC_NDRY, TC_NFRIZZED, MC_NLOW);
/* Check if it is suitable to start a river on the current tile.
*/
@@ -1062,6 +1164,7 @@
current_riverlength, desirable_riverlength, iteration_counter);
} /* end while; */
free(river_map);
+ destroy_placed_map();
river_map = NULL;
}
@@ -1191,8 +1294,8 @@
make_deserts();
make_plains();
make_fair();
+ destroy_placed_map();
make_rivers();
- remove_placed_map();
assign_continent_numbers();
}
@@ -1820,8 +1923,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_condition(&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 +1936,7 @@
}
}
}
- remove_placed_map();
+ destroy_placed_map();
}
/****************************************************************************
@@ -1895,9 +1997,9 @@
long int totalmass;
};
-static bool map_pos_is_cold(int x, int y)
+static bool map_pos_is_cold_or_frizzed(int x, int y)
{
- return map_temperature(x, y) <= 2 * MAX_TEMP/ 10;
+ return map_temperature(x, y) <= COLD_LEVEL;
}
/**************************************************************************
@@ -1967,7 +2069,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 +2538,7 @@
}
make_plains();
- remove_placed_map();
+ destroy_placed_map();
free(height_map);
height_map = NULL;
@@ -2524,7 +2626,7 @@
}
make_plains();
- remove_placed_map();
+ destroy_placed_map();
free(height_map);
height_map = NULL;
@@ -2592,7 +2694,7 @@
make_island(10 * pstate->totalmass / totalweight, 0, pstate, DMSIS);
}
make_plains();
- remove_placed_map();
+ destroy_placed_map();
free(height_map);
height_map = NULL;
- [Freeciv-Dev] (PR#9956) PATCH new rand_map_pos_condition tool for mapgen code,
Marcelo Burda <=
|
|