Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2004:
[Freeciv-Dev] (PR#9637) Ocean numbers
Home

[Freeciv-Dev] (PR#9637) Ocean numbers

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9637) Ocean numbers
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxxx>
Date: Sun, 8 Aug 2004 12:13:57 -0700
Reply-to: rt@xxxxxxxxxxx

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

Here is the first version of the patch that introduces ocean numbers.

Very limited testing is done.

Here are my assumptions (correct me if I am wrong):
1. continent numbers are not saved nor loaded,
2. nowhere in the code continent==0 is used as a check for ocean
3. nowhere, after the map, is generated continent==1 or 2 is used as a
check for polar regions

Maybe some more but don't remember now.

G.
? cont.txt
? isles.gz
? rrr
? ttt.diff
? ttt.gz
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.203
diff -u -r1.203 map.h
--- common/map.h        5 Aug 2004 10:41:34 -0000       1.203
+++ common/map.h        8 Aug 2004 19:09:19 -0000
@@ -44,7 +44,7 @@
                           Player_no is index */
   int assigned; /* these can save a lot of CPU usage -- Syela */
   struct city *worked;      /* city working tile, or NULL if none */
-  unsigned short continent;
+  signed short continent;
   signed char move_cost[8]; /* don't know if this helps! */
   struct player *owner;     /* Player owning this tile, or NULL. */
   struct {
@@ -169,6 +169,7 @@
   bool have_huts;
   bool have_rivers_overlay;    /* only applies if !have_specials */
   int num_continents;
+  int num_oceans;
   struct tile *tiles;
 
   /* Only used by server. */
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.142
diff -u -r1.142 mapgen.c
--- server/mapgen.c     5 Aug 2004 10:41:34 -0000       1.142
+++ server/mapgen.c     8 Aug 2004 19:09:20 -0000
@@ -1203,48 +1203,62 @@
 }
 
 /**************************************************************************
- Number this tile and recursive adjacent tiles with specified
- continent number, by flood-fill algorithm.
+  Number this tile and recursive adjacent tiles with specified
+  continent number, by flood-fill algorithm.
+  is_land tells us whether we are assigning continent numbers or ocean 
+  numbers.
 **************************************************************************/
-static void assign_continent_flood(int x, int y, int nr)
+static void assign_continent_flood(int x, int y, bool is_land, int nr)
 {
   if (map_get_continent(x, y) != 0) {
     return;
   }
 
-  if (is_ocean(map_get_terrain(x, y))) {
+  if ((is_land && is_ocean(map_get_terrain(x, y)))
+      || (!is_land && !is_ocean(map_get_terrain(x, y)))) {
     return;
   }
 
   map_set_continent(x, y, nr);
 
   adjc_iterate(x, y, x1, y1) {
-    assign_continent_flood(x1, y1, nr);
+    assign_continent_flood(x1, y1, is_land, nr);
   } adjc_iterate_end;
 }
 
 /**************************************************************************
- Assign continent numbers to all tiles.
- Also sets map.num_continents (note 0 is ocean, and continents
- have numbers 1 to map.num_continents _inclusive_).
- Note this is not used by generators 2,3 or 4 at map creation
- time, as these assign their own continent numbers.
+  Assign continent and ocean numbers to all tiles, set map.num_continents 
+  and map.num_oceans.
+  Continents have numbers 1 to map.num_continents _inclusive_.
+  Oceans have (negative) numbers -1 to -map.num_oceans _inclusive_.
 **************************************************************************/
 void assign_continent_numbers(void)
 {
+  /* Initialize */
   map.num_continents = 0;
+  map.num_oceans = 0;
   whole_map_iterate(x, y) {
     map_set_continent(x, y, 0);
   } whole_map_iterate_end;
 
+  /* Assign continent numbers */
   whole_map_iterate(x, y) {
     if (map_get_continent(x, y) == 0 
         && !is_ocean(map_get_terrain(x, y))) {
-      assign_continent_flood(x, y, ++map.num_continents);
+      assign_continent_flood(x, y, TRUE, ++map.num_continents);
     }
   } whole_map_iterate_end;
 
-  freelog(LOG_VERBOSE, "Map has %d continents", map.num_continents);
+  /* Assign ocean numbers */
+  whole_map_iterate(x, y) {
+    if (map_get_continent(x, y) == 0 
+        && is_ocean(map_get_terrain(x, y))) {
+      assign_continent_flood(x, y, FALSE, --map.num_oceans);
+    }
+  } whole_map_iterate_end;
+
+  freelog(LOG_VERBOSE, "Map has %d continents and %d oceans", 
+         map.num_continents, map.num_oceans);
 }
 
 /****************************************************************************
@@ -2326,7 +2340,9 @@
   } whole_map_iterate_end;
   if (!map.alltemperate) {
     make_polar();
-    assign_continent_numbers(); /* set poles numbers */
+    /* Set poles numbers.  After the map is generated continents will 
+     * be renumbered. */
+    assign_continent_numbers(); 
   }
   make_island(0, 0, pstate, 0);
   islands[2].starters = 0;
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.136
diff -u -r1.136 maphand.c
--- server/maphand.c    28 Jul 2004 15:24:43 -0000      1.136
+++ server/maphand.c    8 Aug 2004 19:09:20 -0000
@@ -1332,98 +1332,36 @@
 }
 
 /**************************************************************************
-  Recursively renumber the client continent at (x,y) with continent
-  number 'new'.  Ie, renumber (x,y) tile and recursive adjacent
-  land tiles with the same previous continent ('old').
-**************************************************************************/
-static void renumber_continent(int x, int y, int newnum)
-{
-  unsigned short old;
+  Checks for continent change after ocean<-->land change at (x,y).
 
-  if(!normalize_map_pos(&x, &y)) {
-    return;
-  }
-  
-  old = map_get_continent(x, y);
-  
-  map_set_continent(x, y, newnum);
-  adjc_iterate(x, y, i, j) {
-    if (!is_ocean(map_get_terrain(i, j))
-        && map_get_continent(i, j) == old) {
-      freelog(LOG_DEBUG,
-              " renumbering continent %d to %d at (%d %d)", old, newnum, i, j);
-      renumber_continent(i, j, newnum);
-    }
-  } adjc_iterate_end;
-}
-
-/**************************************************************************
-  We just transformed (x,y). If we changed it from ocean to land, check to
-  see if we merged a continent. (assign a continent number if we didn't)
-  If we changed it from land to ocean, check to see if we split a continent 
-  in pieces.
-
-  There are two special cases: we raised atlantis and have ourselves a shiny
-  new island. so we set it to map.num_continents + 1 (this btw is impossible
-  under the current transform rules, but it's an easy enough case that we 
-  check for it here anyway), or we sunk a little atoll. In that case, we'll 
-  return FALSE, even though we lost a continent. 
-  It shouldn't make a difference.
-
-  As a bonus, we set the transformed tile's new continent number here.
+  The check is based on the reasoning that if continent renumbering does 
+  change the continent and ocean numbers, this change _must_ manifest 
+  itself around the tile which was changed (as well as in other places).  
+  So we save all continent numbers, renumber the continents and check 
+  the new numbers against the saved ones.
 **************************************************************************/
-static bool check_for_continent_change(int x, int y)
+static void check_continent_change(int x, int y)
 {
-  unsigned short con = 0, unused = map.num_continents + 1;
+  int old_num[8];
+  bool change = FALSE;
 
-  if (is_ocean(map_get_terrain(x, y))) {
-    map_set_continent(x, y, 0);
-    /* check for land surrounding this tile. */
-    adjc_iterate(x, y, i, j) {
-      if (!is_ocean(map_get_terrain(i, j))) {
-        /* we found a land tile, check for another */
-        adjc_iterate(x, y, l, m) {
-          if (!(l == i && j == m) && !is_ocean(map_get_terrain(l, m))) {
-            /* we found a second adjacent land tile. renumber it */
-            con = map_get_continent(l, m);
-            renumber_continent(l, m, unused);
-
-            /* did the original tile get renumbered? if it did, then we
-             * didn't split the continent. if it's different, then 
-             * we are the proud owner of separate continents */
-            if (map_get_continent(i, j) == unused) {
-              renumber_continent(l, m, con);
-            } else {
-              return TRUE;
-            }
-          }
-        } adjc_iterate_end; 
-      }
-    } adjc_iterate_end;
-  } else {
-    /* check for land surrounding this tile. */
-    adjc_iterate(x, y, i, j) {
-      if (!is_ocean(map_get_terrain(i, j))) {
-        if (con == 0) {
-          con = map_get_continent(i, j);
-        } else if (map_get_continent(i, j) != con) {
-          return TRUE;
-        }
-      }
-    } adjc_iterate_end;
-
-    if (con == 0) {
-      /* we raised atlantis */
-      map_set_continent(x, y, ++map.num_continents);
-
-      allot_island_improvs();
-    } else {
-      /* set the tile to something adjacent to it */
-      map_set_continent(x, y, con);
-    }
+  /* Save the old numbers */
+  adjc_dir_iterate(x, y, x1, y1, dir) {
+    old_num[dir] = map_get_continent(x1, y1);
+  } adjc_dir_iterate_end;
+
+  /* Assign the new numbers */
+  assign_continent_numbers();
+
+  /* Check if the numbers changed */
+  adjc_dir_iterate(x, y, x1, y1, dir) {
+    change = (change || (old_num[dir] != map_get_continent(x1, y1)));
+  } adjc_dir_iterate_end;
+
+  if (change) {
+    allot_island_improvs();
+    send_all_known_tiles(NULL);
   }
-
-  return FALSE;
 }
 
 /**************************************************************************
@@ -1431,7 +1369,7 @@
   (Should be called after any potential ocean/land terrain changes.)
   Also, returns an enum ocean_land_change, describing the change, if any.
 
-  if we did a land change, we do everything in our power to avoid reassigning
+  if we did a land change, we try to avoid reassigning
   continent numbers.
 **************************************************************************/
 enum ocean_land_change check_terrain_ocean_land_change(int x, int y,
@@ -1444,13 +1382,7 @@
     ocean_to_land_fix_rivers(x, y);
     city_landlocked_sell_coastal_improvements(x, y);
 
-    if (check_for_continent_change(x, y)) {
-      assign_continent_numbers();
-
-      allot_island_improvs();
-
-      send_all_known_tiles(NULL);
-    }
+    check_continent_change(x, y);
     
     map_update_borders_landmass_change(x, y);
 
@@ -1459,13 +1391,7 @@
   } else if (!is_ocean(oldter) && is_ocean(newter)) {
     /* land to ocean ... */
 
-    if (check_for_continent_change(x, y)) {
-      assign_continent_numbers();
-
-      allot_island_improvs();
-
-      send_all_known_tiles(NULL);
-    }
+    check_continent_change(x, y);
 
     map_update_borders_landmass_change(x, y);
 
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.45
diff -u -r1.45 sanitycheck.c
--- server/sanitycheck.c        27 Jul 2004 16:43:48 -0000      1.45
+++ server/sanitycheck.c        8 Aug 2004 19:09:20 -0000
@@ -103,10 +103,15 @@
     struct tile *ptile = map_get_tile(x, y);
     struct city *pcity = map_get_city(x, y);
     int cont = map_get_continent(x, y);
+
+    assert(cont != 0);
     if (is_ocean(map_get_terrain(x, y))) {
-      assert(cont == 0);
+      adjc_iterate(x, y, x1, y1) {
+       if (is_ocean(map_get_terrain(x1, y1))) {
+         assert(map_get_continent(x1, y1) == cont);
+       }
+      } adjc_iterate_end;
     } else {
-      assert(cont != 0);
       adjc_iterate(x, y, x1, y1) {
        if (!is_ocean(map_get_terrain(x1, y1))) {
          assert(map_get_continent(x1, y1) == cont);
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.179
diff -u -r1.179 srv_main.c
--- server/srv_main.c   5 Aug 2004 11:34:18 -0000       1.179
+++ server/srv_main.c   8 Aug 2004 19:09:20 -0000
@@ -1688,9 +1688,7 @@
     map_fractal_generate();
   }
 
-  if (map.num_continents == 0) {
-    assign_continent_numbers();
-  }
+  assign_continent_numbers();
 
   gamelog_map();
   /* start the game */

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#9637) Ocean numbers, Gregory Berkolaiko <=