Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#9921) percentages for count_xxx_near_tile
Home

[Freeciv-Dev] (PR#9921) percentages for count_xxx_near_tile

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9921) percentages for count_xxx_near_tile
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 3 Sep 2004 08:35:08 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=9921 >

This patch changes count_xxx_near_tile to optionally return percentage 
values rather than the number of tiles.  This is controlled by a 
parameter to the function.

This is useful because almost all callers need to know the percentage, 
not the actual number.  With hex and rectangular tiles the two will not 
correspond.

I decided it was easiest just to add a new parameter to the functions. 
But it would also be possible to duplicate the functions.  Of course in 
theory we could have 4 functions of each type:

   count_xxx_near_tile
   count_xxx_near_tile_cardinal
   count_xxx_near_tile_pct
   count_xxx_near_tile_cardinal_pct

and the number of options could keep growing, making the number of 
functions increase exponentially.  Though in practice most of these 
variants aren't needed.

This patch does introduce one change: the percentage is calculated based 
on the number of adjacent tiles not the total number of directions.  On 
the edge of the map this means that all percentages will still sum up to 
100 (ignoring rounding errors).  But checks like 
adjacent-land-to-transform-ocean will have their behavior changed 
slightly (except that adjacent-land-to-transform-ocean doesn't use these 
functions yet).

Please comment.

jason

Index: common/terrain.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.c,v
retrieving revision 1.14
diff -u -r1.14 terrain.c
--- common/terrain.c    3 Sep 2004 15:12:26 -0000       1.14
+++ common/terrain.c    3 Sep 2004 15:29:52 -0000
@@ -172,17 +172,22 @@
 /****************************************************************************
   Return the number of adjacent tiles that have the given terrain.
 ****************************************************************************/
-int count_terrain_near_tile(int map_x, int map_y, bool cardinal_only,
+int count_terrain_near_tile(int map_x, int map_y,
+                           bool cardinal_only, bool percentage,
                            Terrain_type_id t)
 {
-  int count = 0;
+  int count = 0, total = 0;
 
   variable_adjc_iterate(map_x, map_y, adjc_x, adjc_y, cardinal_only) {
     if (map_get_terrain(adjc_x, adjc_y) == t) {
       count++;
     }
+    total++;
   } variable_adjc_iterate_end;
 
+  if (percentage) {
+    count = count * 100 / total;
+  }
   return count;
 }
 
@@ -203,17 +208,22 @@
 /****************************************************************************
   Returns the number of adjacent tiles that have the given map special.
 ****************************************************************************/
-int count_special_near_tile(int map_x, int map_y, bool cardinal_only,
+int count_special_near_tile(int map_x, int map_y,
+                           bool cardinal_only, bool percentage,
                            enum tile_special_type spe)
 {
-  int count = 0;
+  int count = 0, total = 0;
 
   variable_adjc_iterate(map_x, map_y, adjc_x, adjc_y, cardinal_only) {
     if (map_has_special(adjc_x, adjc_y, spe)) {
       count++;
     }
+    total++;
   } variable_adjc_iterate_end;
 
+  if (percentage) {
+    count = count * 100 / total;
+  }
   return count;
 }
 
@@ -235,16 +245,21 @@
 /****************************************************************************
   Return the number of adjacent tiles that have terrain with the given flag.
 ****************************************************************************/
-int count_terrain_flag_near_tile(int map_x, int map_y, bool cardinal_only,
+int count_terrain_flag_near_tile(int map_x, int map_y,
+                                bool cardinal_only, bool percentage,
                                 enum terrain_flag_id flag)
 {
-  int count = 0;
+  int count = 0, total = 0;
 
   variable_adjc_iterate(map_x, map_y, adjc_x, adjc_y, cardinal_only) {
     if (terrain_has_flag(map_get_terrain(adjc_x, adjc_y), flag)) {
       count++;
     }
+    total++;
   } variable_adjc_iterate_end;
 
+  if (percentage) {
+    count = count * 100 / total;
+  }
   return count;
 }
Index: common/terrain.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/terrain.h,v
retrieving revision 1.24
diff -u -r1.24 terrain.h
--- common/terrain.h    3 Sep 2004 15:12:26 -0000       1.24
+++ common/terrain.h    3 Sep 2004 15:29:52 -0000
@@ -114,24 +114,27 @@
 
 /* Functions to operate on a general terrain type. */
 bool is_terrain_near_tile(int map_x, int map_y, Terrain_type_id t);
-int count_terrain_near_tile(int map_x, int map_y, bool cardinal_only,
+int count_terrain_near_tile(int map_x, int map_y,
+                           bool cardinal_only, bool percentage,
                            Terrain_type_id t);
 
 /* Functions to operate on a terrain special. */
 bool is_special_near_tile(int map_x, int map_y, enum tile_special_type spe);
-int count_special_near_tile(int map_x, int map_y, bool cardinal_only,
+int count_special_near_tile(int map_x, int map_y,
+                           bool cardinal_only, bool percentage,
                            enum tile_special_type spe);
 
 /* Functions to operate on a terrain flag. */
 bool is_terrain_flag_near_tile(int x, int y, enum terrain_flag_id flag);
-int count_terrain_flag_near_tile(int x, int y, bool cardinal_only,
+int count_terrain_flag_near_tile(int x, int y,
+                                bool cardinal_only, bool percentage,
                                 enum terrain_flag_id flag);
 
 /* Terrain-specific functions. */
 #define is_ocean(x) (terrain_has_flag((x), TER_OCEANIC))
 #define is_ocean_near_tile(x, y) is_terrain_flag_near_tile(x, y, TER_OCEANIC)
-#define count_ocean_near_tile(x, y, cardinal_only)             \
-  count_terrain_flag_near_tile(x, y, cardinal_only, TER_OCEANIC)
+#define count_ocean_near_tile(x, y, cardinal_only, percentage)         \
+  count_terrain_flag_near_tile(x, y, cardinal_only, percentage, TER_OCEANIC)
 
 /* This iterator iterates over all terrain types. */
 #define terrain_type_iterate(id)                                            \
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.154
diff -u -r1.154 mapgen.c
--- server/mapgen.c     3 Sep 2004 15:12:26 -0000       1.154
+++ server/mapgen.c     3 Sep 2004 15:29:53 -0000
@@ -610,7 +610,7 @@
 *********************************************************************/
 static int river_test_rivergrid(int x, int y)
 {
-  return (count_special_near_tile(x, y, TRUE, S_RIVER) > 1) ? 1 : 0;
+  return (count_special_near_tile(x, y, TRUE, FALSE, S_RIVER) > 1) ? 1 : 0;
 }
 
 /*********************************************************************
@@ -627,9 +627,7 @@
 *********************************************************************/
 static int river_test_adjacent_ocean(int x, int y)
 {
-  /* This number must always be >= 0.  6 is the maximum number of
-   * cardinal directions. */
-  return 6 - count_ocean_near_tile(x, y, TRUE);
+  return 100 - count_ocean_near_tile(x, y, TRUE, TRUE);
 }
 
 /*********************************************************************
@@ -637,9 +635,7 @@
 *********************************************************************/
 static int river_test_adjacent_river(int x, int y)
 {
-  /* This number must always be >= 0.  6 is the maximum number of
-   * cardinal directions. */
-  return 6 - count_special_near_tile(x, y, TRUE, S_RIVER);
+  return 100 - count_special_near_tile(x, y, TRUE, TRUE, S_RIVER);
 }
 
 /*********************************************************************
@@ -647,8 +643,8 @@
 *********************************************************************/
 static int river_test_adjacent_highlands(int x, int y)
 {
-  return (count_terrain_near_tile(x, y, TRUE, T_HILLS)
-         + 2 * count_terrain_near_tile(x, y, TRUE, T_MOUNTAINS));
+  return (count_terrain_near_tile(x, y, TRUE, TRUE, T_HILLS)
+         + 2 * count_terrain_near_tile(x, y, TRUE, TRUE, T_MOUNTAINS));
 }
 
 /*********************************************************************
@@ -664,9 +660,7 @@
 *********************************************************************/
 static int river_test_adjacent_swamp(int x, int y)
 {
-  /* This number must always be >= 0.  6 is the maximum number of
-   * cardinal directions. */
-  return 6 - count_terrain_near_tile(x, y, TRUE, T_SWAMP);
+  return 100 - count_terrain_near_tile(x, y, TRUE, TRUE, T_SWAMP);
 }
 
 /*********************************************************************
@@ -765,16 +759,13 @@
      (river_test_adjacent_ocean)
      Rivers must flow down to coastal areas when possible:
 
-     Possible values:
-     n: 4 - adjacent_terrain_tiles4(...)
+     Possible values: 0-100
 
  * Adjacent river:
      (river_test_adjacent_river)
      Rivers must flow down to areas near other rivers when possible:
 
-     Possible values:
-     n: 6 - count_river_near_tile(...) (should be small after the
-                                        river-grid test)
+     Possible values: 0-100
                                        
  * Adjacent highlands:
      (river_test_adjacent_highlands)
@@ -823,8 +814,8 @@
 
     /* Test if the river is done. */
     /* We arbitrarily make rivers end at the poles. */
-    if (count_special_near_tile(x, y, TRUE, S_RIVER) != 0
-       || count_ocean_near_tile(x, y, TRUE) != 0
+    if (count_special_near_tile(x, y, TRUE, TRUE, S_RIVER) > 0
+       || count_ocean_near_tile(x, y, TRUE, TRUE) > 0
         || (map_get_terrain(x, y) == T_ARCTIC 
            && map_temperature(x, y) < 8 * MAX_TEMP / 100)) { 
 
@@ -967,14 +958,14 @@
 
        /* Don't start a river on a tile is surrounded by > 1 river +
           ocean tile. */
-       && (count_special_near_tile(x, y, TRUE, S_RIVER)
-           + count_ocean_near_tile(x, y, TRUE) <= 1)
+       && (count_special_near_tile(x, y, TRUE, FALSE, S_RIVER)
+           + count_ocean_near_tile(x, y, TRUE, FALSE) <= 1)
 
        /* Don't start a river on a tile that is surrounded by hills or
           mountains unless it is hard to find somewhere else to start
           it. */
-       && (count_terrain_near_tile(x, y, TRUE, T_HILLS)
-           + count_terrain_near_tile(x, y, TRUE, T_MOUNTAINS) < 4
+       && (count_terrain_near_tile(x, y, TRUE, TRUE, T_HILLS)
+           + count_terrain_near_tile(x, y, TRUE, TRUE, T_MOUNTAINS) < 90
            || iteration_counter == RIVERS_MAXTRIES / 10 * 5)
 
        /* Don't start a river on hills unless it is hard to find
@@ -1982,12 +1973,12 @@
       /* the first condition helps make terrain more contiguous,
         the second lets it avoid the coast: */
       if ((i * 3 > k * 2 
-          || count_special_near_tile(x, y, FALSE, S_RIVER) > 0
+          || count_special_near_tile(x, y, FALSE, TRUE, S_RIVER) > 0
           || myrand(100) < 50)
          && (!is_cardinally_adj_to_ocean(x, y) || myrand(100) < coast)) {
        if (is_water_adjacent_to_tile(x, y)
-           && count_ocean_near_tile(x, y, FALSE) < 4
-            && count_special_near_tile(x, y, FALSE, S_RIVER) < 3) {
+           && count_ocean_near_tile(x, y, FALSE, TRUE) < 50
+            && count_special_near_tile(x, y, FALSE, TRUE, S_RIVER) < 35) {
          map_set_special(x, y, S_RIVER);
          i--;
        }

[Prev in Thread] Current Thread [Next in Thread]