Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2004:
[Freeciv-Dev] (PR#9818) Inland lakes and borders
Home

[Freeciv-Dev] (PR#9818) Inland lakes and borders

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9818) Inland lakes and borders
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Fri, 27 Aug 2004 08:21:56 -0700
Reply-to: rt@xxxxxxxxxxx

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

- MAXIMUM_CLAIMED_OCEAN_SIZE (20)
+ MAXIMUM_CLAIMED_OCEAN_SIZE (20)
Index: maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.143
diff -u -r1.143 maphand.c
--- maphand.c   24 Aug 2004 20:27:11 -0000      1.143
+++ maphand.c   26 Aug 2004 12:15:17 -0000
@@ -40,6 +40,14 @@
 
 #include "maphand.h"
 
+#define MAXIMUM_CLAIMED_OCEAN_SIZE (20)
+
+/* Continent which is adjacent to a given ocean. -1 if the ocean is surrounded
+   by more than one continent */
+Continent_id lake_surrounders[MAP_NCONT];
+
+int ocean_sizes[MAP_NCONT];
+
 /**************************************************************************
   Number this tile and nearby tiles (recursively) with the specified
   continent number, using a flood-fill algorithm.
@@ -65,11 +73,45 @@
 }
 
 /**************************************************************************
+  Calculate lake_surrounders[] and ocean_sizes[] arrays
+**************************************************************************/
+static void calculate_inland_lakes(void)
+{
+  int i;
+
+  for (i = 1; i <= map.num_oceans; i++) {
+    ocean_sizes[i] = 0;
+    lake_surrounders[i] = 0;
+  }
+  
+  whole_map_iterate(x, y) {
+    Continent_id cont = map_get_continent(x, y);
+    if (cont > 0) {
+      /* land */
+      adjc_iterate(x, y, x2, y2) {
+        Continent_id cont2 = map_get_continent(x2, y2);
+       if (cont2 < 0) {
+         if (lake_surrounders[-cont2] == 0) {
+           lake_surrounders[-cont2] = cont;
+         } else if (lake_surrounders[-cont2] != cont) {
+           lake_surrounders[-cont2] = -1;
+         }
+       }
+      } adjc_iterate_end;
+    } else {
+      ocean_sizes[-cont]++;
+    }
+  } whole_map_iterate_end;
+}
+
+/**************************************************************************
   Assign continent and ocean numbers to all tiles, and 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_.
+  
+  Also recalculate ocean_sizes[] and lake_surrounders[] arrays
 **************************************************************************/
 void assign_continent_numbers(void)
 {
@@ -98,6 +140,8 @@
     }
   } whole_map_iterate_end;
 
+  calculate_inland_lakes();
+
   freelog(LOG_VERBOSE, "Map has %d continents and %d oceans", 
          map.num_continents, map.num_oceans);
 }
@@ -1410,37 +1454,47 @@
 }
 
 /*************************************************************************
-  Returns TRUE if the given ocean tile is surrounded by at least 5 land
-  tiles of the same continent (N.B. will probably need modifications to
-  deal with topologies in which tiles do not have 8 neighbours). If this
-  is the case, the continent number of the land tiles is returned in *contp.
-  If multiple continents border the tile, FALSE is always returned.
-  This enables small seas (usually long inlets or inland lakes) to be
-  claimed by nations, rather than remaining as international waters. This
-  should in the long run perhaps be replaced with more general detection
-  of inland seas.
+  Ocean tile can be claimed iff one of the following conditions stands:
+  a) it is an inland lake not larger than MAXIMUM_OCEAN_SIZE
+  b) it is adjacent to only one continent and not more than two ocean tiles
+  c) It is one tile away from a city (This function doesn't check it)
+  The city, which claims the ocean has to be placed on the correct continent.
+  in case a) The continent which surrounds the inland lake
+  in case b) The only continent which is adjacent to the tile
+  The correct continent is returned in *contp.
 *************************************************************************/
 static bool is_claimed_ocean(int x, int y, Continent_id *contp)
 {
-  Continent_id cont = 0, numland = 0;
-
-  adjc_iterate(x, y, xp, yp) {
-    if (!is_ocean(map_get_terrain(xp, yp))) {
-      Continent_id thiscont = map_get_continent(xp, yp);
-
-      if (cont == 0) {
-       cont = thiscont;
-      }
-      if (cont == thiscont) {
-       numland++;
-      } else {
-       return FALSE;
+  Continent_id cont = map_get_continent(x, y);
+  Continent_id cont2, other;
+  int ocean_tiles;
+  
+  if (ocean_sizes[-cont] <= MAXIMUM_CLAIMED_OCEAN_SIZE &&
+      lake_surrounders[-cont] > 0) {
+    *contp = lake_surrounders[-cont];
+    return TRUE;
+  }
+  
+  other = 0;
+  ocean_tiles = 0;
+  adjc_iterate(x, y, x2, y2) {
+    cont2 = map_get_continent(x2, y2);
+    if (cont2 == cont) {
+      ocean_tiles++;
+    } else {
+      if (other == 0) {
+        other = cont2;
+      } else if (other != cont2) {
+        return FALSE;
       }
     }
   } adjc_iterate_end;
-
-  *contp = cont;
-  return (numland >= 5);
+  if (ocean_tiles <= 2) {
+    *contp = other;
+    return TRUE;
+  } else {
+    return FALSE;
+  }
 }
 
 /*************************************************************************

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