Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] Re: PATCH: rand_pos function and usage (PR#1017)
Home

[Freeciv-Dev] Re: PATCH: rand_pos function and usage (PR#1017)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: PATCH: rand_pos function and usage (PR#1017)
From: Jason Dorje Short <vze2zq63@xxxxxxxxxxx>
Date: Fri, 19 Oct 2001 14:48:45 -0400
Reply-to: jdorje@xxxxxxxxxxxx

Raimar Falke wrote:
> 
> On Fri, Oct 19, 2001 at 07:16:42AM -0400, Jason Dorje Short wrote:
> > Raimar Falke wrote:
> > >
> > > On Thu, Oct 18, 2001 at 11:53:08AM -0700, jdorje@xxxxxxxxxxxxxxxxxxxxx 
> > > wrote:
> > > > Raimar Falke wrote:
> > > > >
> > > > > On Thu, Oct 18, 2001 at 11:13:48AM -0700, 
> > > > > jdorje@xxxxxxxxxxxxxxxxxxxxx wrote:
> > > > > > Raimar Falke wrote:
> > > > > > >
> > > > > > > On Wed, Oct 17, 2001 at 10:01:24PM -0700, 
> > > > > > > jdorje@xxxxxxxxxxxxxxxxxxxxx wrote:
> > > > > > > > The attached patch creates a function, rand_pos(&x, &y) that 
> > > > > > > > determines
> > > > > > > > a random map position.  It also uses it in place of all similar 
> > > > > > > > code.
> > > > > >
> > > > > > > > This could have efficiency problems if we were looking for a 
> > > > > > > > very small
> > > > > > > > subset of positions on the map.  Fortunately, there is no such 
> > > > > > > > code
> > > > > > > > right now.
> > > > > > >
> > > > > > > I'm also converned about efficiency problems. Can't rand_pos take 
> > > > > > > the
> > > > > > > range of allowed distances from north. Which now are from
> > > > > > > 0..map.ysize-1 and latter come from 0..height-1.
> > > > > >
> > > > > > This doesn't sound so good.  Outside of map generation stuff (which
> > > > > > shouldn't be a concern), the only check that's done on the returned
> > > > > > value is to make sure it's not on one of the poles.  In other words,
> > > > > > this will attain virtually no speedup except during map generation.
> > > > > >
> > > > > > This method also isn't really very general.  For instance, how does 
> > > > > > it
> > > > > > apply to a torus map?  A torus map would probably have no polar 
> > > > > > regions
> > > > > > (everything would be tropical); this would be easy to achieve using 
> > > > > > the
> > > > > > checks I'm proposing but difficult or impossible if you build that
> > > > > > information into the rand_pos function.
> > > > > >
> > > > > > Finnaly, this would make the code much uglier (IMO) and would make
> > > > > > rand_pos a topology-dependent function, which I'd like to avoid.
> > > > >
> > > > > The map generation is topology-dependent. The placement of certain
> > > > > items (rand_pos is used for this) is topology-dependent. So I have no
> > > > > problem of having a topology-dependent rand_pos method. This method
> > > > > has to have a certain knowledge about latitude. But method for this
> > > > > are needed for the general map creation anyway.
> > > > >
> > > > > So what do you think about a general rand_pos method and a map
> > > > > generation rand_pos method. The second one is local to mapgen.[ch].
> > > >
> > > > I don't think map generation has to be particularly topology-dependent,
> > > > at least not the part you're talking about.
> > > >
> > > > BTW: the map iteration patch did not touch mapgen.c because I plan a
> > > > separate fix for there.
> > > >
> > > > I plan a macro DISTANCE_FROM_NORTH_POLE(x,y) which will replace the
> > > > current use of "y" in most of these places.  Similarly, a macro
> > > > DISTANCE_FROM_SOUTH_POLE(x,y) can replace the current use of
> > >
> > > The DISTANCE_FROM_SOUTH_POLE isn't needed since
> > > DISTANCE_FROM_SOUTH_POLE = height - DISTANCE_FROM_NORTH_POLE. But
> > > you may introduce a DISTANCE_FROM_WEST_POLE.
> >
> > Not necessarily.  You're thinking linearly, whereas not all topologies
> > may work this way.  For instance, an ellipse may have positions on the
> > side be closer to the poles than positions in the interior that are at
> > the same altitude, in this way getting a polar cover at more than just
> > the top and bottom rows of the map.  This will lead to the distances not
> > being continuous.
> >
> > More generally, on an actual sphere the distances from north and south
> > poles always add up.  But on a differently shaped world, they need not.
> > In this context, TOTAL_POLAR_DISTANCE() is just a scale factor.
> >
> > Or, to put it yet another way, we're usually only concerned with the
> > distance to the nearest pole, which is much easier to compute for most
> > maps and is what we're interested in.  Since this nearest pole may be
> > either north or south, it might be easier to have code in both macros to
> > compute distance.
> >
> > Or, to put it yet another way, we may end up defining
> > DISTANCE_FROM_SOUTH_POLE as
> > TOTAL_POLAR_DISTANCE()-DISTANCE_FROM_NORTH_POLE(x,y).
> >
> > > > "map.ysize-1-y" (which is sometimes incorrectly referred to as
> > > > "map.ysize-y", I believe).  Instead of using map.ysize in the
> > > > calculations, we'll use TOTAL_POLAR_DISTANCE().  Introducing a fourth
> > > > macro, DISTANCE_FROM_POLE(x,y) to be the minimum of the distance from
> > > > the north and south pole allows lots of the code to be made much
> > > > cleaner.
> > > >
> > > > These macros (well, all but the fourth one) are topology-dependent, but
> > > > they're pretty easy to write for most topologies.  Using them will make
> > > > it pretty easy for specific topologies to have different types of maps
> > > > under the same mapgen code: for instance a torus map would probably not
> > > > have any poles, so would always have
> > > > DISTANCE_FROM_POLE(x,y)==TOTAL_POLAR_DISTANCE()/2, making everything
> > > > tropical.  (This idea was proposed by Reinier; a torus map done this way
> > > > makes things fairer in multiplayer mode.)  It is not easily achievable
> > > > if things are done as you propose.
> > > >
> > > > Ultimately, there may be more problems with the mapgen code and some map
> > > > generators may not work for specific topologies.  This will be a deeper
> > > > problem, though, and won't have such a simple solution.
> > >
> > > I think the idea is good but need integration into the (to be created)
> > > framework. So if there is a map.topology.height there should be a
> > > get_height_of_map_pos(x,y) which has a range of
> > > [0..map.topology.height-1]. Same for width. Or an
> > > transform_to_xyz_system(&width,&height,x,y). The question is: how is
> > > the new system named?
> >
> > This makes sense.  But, map.topology.height might not equate to
> > TOTAL_POLAR_DISTANCE().  Then again, it might.  It depends on how we
> > implement it.
> >
> > Another problem is this forces map generation code to assume the poles
> > are located at height==0 and height==map.topology.height-1, which may
> > not be the case.  Having DISTANCE_FROM_***_POLE as a wrapper still
> > allows us to use this sort of system as a backend.
> >
> > So, in summary using functions/macros to access all this data gives us a
> > lot of flexibility.  But we still need to decide what form the backend
> > accesses should take.
> >
> > Here's another question: there's really two different checks here,
> > DISTANCE_FROM_POLE and DISTANCE_FROM_EDGE.  An "edge" is the edge of the
> > map, where it does not wrap around.  Under the current topology
> > DISTANCE_FROM_POLE(x,y)==DISTANCE_FROM_EDGE(x,y).  The question is,
> > which is intended for each check?
> >
> > Obviously for making arctic regions it is the DISTANCE_FROM_POLE we're
> > interested in.  But for make_passable() it might be DISTANCE_FROM_EDGE.
> > I'm really not sure what's best here.  Running make_passable() on an
> > elliptic map if it uses DISTANCE_FROM_POLE() really wouldn't make all
> > that much sense.
> 
> I know that such distances aren't available on all topologies. However
> the non-iso rectangle and the iso-rectangle has such distances. And
> yes I would also prefer to have a distance_from_[nwse]_edge. This
> would be the base where other stuff like distance_from_[ns]_pole can
> be defined. I also agree that map.topology.height is more a
> map.topology.max_height.

OK, so we have distance_from_[nwse]_border - let's call a border area
where wrapping may occur a "border" and one where there is no wrapping
an "edge" (unless you have a better idea; I just want to make the
distinction).  We'll also have distance_from_pole (or maybe
distance_from_[ns]_pole) and distance_from_edge as wrappers.  Then we've
also got the height and width of the map, which may or may not
correspond to map.topology.[height|width], and total_polar_distance as a
wrapper for this.

The attached patch is an example of what I'm looking at for mapgen.c. 
Aside from the rand_pos changes, it converts everything to use
whole_map_iterate with the appropriate polar distance check.  (It has no
appreciable impact on the speed of standard map generation.)

jason
? rc
? old
? topology
? mydiff
? mydiff2
? corecleanup_08.ReadMe
? jasongame-middle3
? topology.c
? client/mapview_common.c
? client/mapview_common.h
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.97
diff -u -r1.97 map.c
--- common/map.c        2001/10/15 13:42:50     1.97
+++ common/map.c        2001/10/19 18:37:10
@@ -1340,6 +1340,17 @@
 }
 
 /**************************************************************************
+Random square anywhere on the map.  Only "normal" positions will be found.
+**************************************************************************/
+void rand_pos(int *x, int *y)
+{
+  do {
+    *x = myrand(map.xsize);
+    *y = myrand(map.ysize);
+  } while (!is_normal_map_pos(*x, *y));
+}
+
+/**************************************************************************
 Random neighbouring square.
 **************************************************************************/
 void rand_neighbour(int x0, int y0, int *x, int *y)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.100
diff -u -r1.100 map.h
--- common/map.h        2001/10/19 08:12:52     1.100
+++ common/map.h        2001/10/19 18:37:11
@@ -286,6 +286,7 @@
 void nearest_real_pos(int *x, int *y);
 
 void rand_neighbour(int x0, int y0, int *x, int *y);
+void rand_pos(int *x, int *y);
 
 int is_water_adjacent_to_tile(int x, int y);
 int is_tiles_adjacent(int x0, int y0, int x1, int y1);
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.35
diff -u -r1.35 barbarian.c
--- server/barbarian.c  2001/10/14 21:02:16     1.35
+++ server/barbarian.c  2001/10/19 18:37:11
@@ -324,8 +324,10 @@
   struct city *pc;
   struct player *barbarians, *victim;
 
-  x = myrand(map.xsize);
-  y = 1 + myrand(map.ysize-2);  /* No uprising on North or South Pole */
+  /* No uprising on North or South Pole */
+  do {
+    rand_pos(&x, &y);
+  } while (y == 0 || y == map.ysize-1);
 
   if( !(pc = dist_nearest_city(NULL, x, y, 1, 0)) )       /* any city */
     return;
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.75
diff -u -r1.75 mapgen.c
--- server/mapgen.c     2001/10/14 21:02:16     1.75
+++ server/mapgen.c     2001/10/19 18:37:12
@@ -30,6 +30,13 @@
 
 #include "mapgen.h"
 
+#define DISTANCE_FROM_NORTH_POLE(x, y) (y)
+#define DISTANCE_FROM_SOUTH_POLE(x, y) (map.ysize - 1 - (y))
+#define DISTANCE_FROM_POLE(x, y)      \
+  MIN(DISTANCE_FROM_NORTH_POLE(x, y), \
+      DISTANCE_FROM_SOUTH_POLE(x, y))
+#define TOTAL_POLAR_DISTANCE( ) (map.ysize)
+
 /* Wrapper for easy access.  It's a macro so it can be a lvalue. */
 #define hmap(x, y) (height_map[map_inx(x, y)])
 #define rmap(x, y) (river_map[map_inx(x, y)])
@@ -105,44 +112,33 @@
 **************************************************************************/
 static void make_polar(void)
 {
-  int y,x;
+  /* The polar area is the top and bottom 10% of the map. */
+  int polar_area = TOTAL_POLAR_DISTANCE()/10;
+  whole_map_iterate(x, y) {
+    enum tile_terrain_type terrain = map_get_terrain(x, y);
+    int dist = DISTANCE_FROM_POLE(x, y);
 
-  for (y=0;y<map.ysize/10;y++) {
-    for (x=0;x<map.xsize;x++) {
-      if ((hmap(x, y)+(map.ysize/10-y*25)>myrand(maxval) &&
-          map_get_terrain(x,y)==T_GRASSLAND) || y==0) { 
-       if (y<2)
-         map_set_terrain(x, y, T_ARCTIC);
-       else
-         map_set_terrain(x, y, T_TUNDRA);
-         
-      } 
-    }
-  }
-  for (y=map.ysize*9/10;y<map.ysize;y++) {
-    for (x=0;x<map.xsize;x++) {
-      if ((hmap(x, y)+(map.ysize/10-(map.ysize-y)*25)>myrand(maxval) &&
-          map_get_terrain(x, y)==T_GRASSLAND) || y==map.ysize-1) {
-       if (y>map.ysize-3)
-         map_set_terrain(x, y, T_ARCTIC);
-       else
-         map_set_terrain(x, y, T_TUNDRA);
-      }
+    if (dist >= polar_area)
+      continue;
+
+    if (dist == 0) {
+      map_set_terrain(x, y, T_ARCTIC);
+      continue;
     }
-  }
+
+    if (hmap(x, y)+(polar_area-dist*25) > myrand(maxval) &&
+       terrain == T_GRASSLAND)
+      map_set_terrain(x, y, dist < 2 ? T_ARCTIC : T_TUNDRA);
 
   /* only arctic and tundra allowed at the poles (first and last two lines,
-     as defined in make_passable() ), to be consistent with generator>1. 
+     as defined in make_passable() ), to be consistent with generator>1.
      turn every land tile on the second lines that is not arctic into tundra,
      since the first lines has already been set to all arctic above. */
-  for (x=0;x<map.xsize;x++) {
-    if (map_get_terrain(x, 1)!=T_ARCTIC &&
-       map_get_terrain(x, 1)!=T_OCEAN)
-      map_set_terrain(x, 1, T_TUNDRA);
-    if (map_get_terrain(x, map.ysize-2)!=T_ARCTIC && 
-       map_get_terrain(x, map.ysize-2)!=T_OCEAN)
-      map_set_terrain(x, map.ysize-2, T_TUNDRA);
-  }
+    if (dist<= 1 &&
+       terrain != T_ARCTIC &&
+       terrain != T_OCEAN)
+      map_set_terrain(x, y, T_TUNDRA);
+  } whole_map_iterate_end;
 }
 
 /**************************************************************************
@@ -172,11 +168,12 @@
 **************************************************************************/
 static void make_forest(int x, int y, int height, int diff)
 {
-  if (y==0 || y==map.ysize-1)
+  int dist = DISTANCE_FROM_POLE(x, y);
+  if (dist == 0)
     return;
 
   if (map_get_terrain(x, y)==T_GRASSLAND) {
-    if (y>map.ysize*42/100 && y<map.ysize*58/100 && myrand(100)>50)
+    if (dist > TOTAL_POLAR_DISTANCE() * 42/100 && myrand(100)>50)
       map_set_terrain(x, y, T_JUNGLE);
     else 
       map_set_terrain(x, y, T_FOREST);
@@ -199,14 +196,14 @@
   int forestsize=25;
   forestsize=(map.xsize*map.ysize*map.forestsize)/1000;
    do {
-    x=myrand(map.xsize);
-    y=myrand(map.ysize);
+    rand_pos(&x, &y);
     if (map_get_terrain(x, y)==T_GRASSLAND) {
       make_forest(x,y, hmap(x, y), 25);
     }
     if (myrand(100)>75) {
-      y=(myrand(map.ysize*2/10))+map.ysize*4/10;
-      x=myrand(map.xsize);
+      do {
+       rand_pos(&x, &y);
+      } while (DISTANCE_FROM_POLE(x, y) < TOTAL_POLAR_DISTANCE() * 4 / 10);
       if (map_get_terrain(x, y)==T_GRASSLAND) {
        make_forest(x,y, hmap(x, y), 25);
       }
@@ -227,8 +224,7 @@
   for (swamps=0;swamps<map.swampsize;) {
     forever++;
     if (forever>1000) return;
-    y=myrand(map.ysize);
-    x=myrand(map.xsize);
+    rand_pos(&x, &y);
     if (map_get_terrain(x, y)==T_GRASSLAND && hmap(x, y)<(maxval*60)/100) {
       map_set_terrain(x, y, T_SWAMP);
       cartesian_adjacent_iterate(x, y, x1, y1) {
@@ -254,17 +250,14 @@
   int x,y,i,j;
   i=map.deserts;
   j=0;
-  while (i && j<500) {
+  while (i && j<1000) {
     j++;
 
-    y=myrand(map.ysize*10/180)+map.ysize*110/180;
-    x=myrand(map.xsize);
-    if (map_get_terrain(x, y)==T_GRASSLAND) {
-      make_desert(x,y, hmap(x, y), 50);
-      i--;
-    }
-    y=myrand(map.ysize*10/180)+map.ysize*60/180;
-    x=myrand(map.xsize);
+    do {
+      rand_pos(&x, &y);
+    } while (DISTANCE_FROM_POLE(x, y) < TOTAL_POLAR_DISTANCE() * 60/180 ||
+            DISTANCE_FROM_POLE(x, y) >= TOTAL_POLAR_DISTANCE() * 70/180);
+
     if (map_get_terrain(x, y)==T_GRASSLAND) {
       make_desert(x,y, hmap(x, y), 50);
       i--;
@@ -658,8 +651,6 @@
   /* The number of river tiles that have been set. */
   int current_riverlength = 0;
 
-  int i; /* Loop variable. */
-
   /* Counts the number of iterations (should increase with 1 during
      every iteration of the main loop in this function).
      Is needed to stop a potentially infinite loop. */
@@ -672,10 +663,9 @@
         iteration_counter < RIVERS_MAXTRIES) {
 
     /* Don't start any rivers at the poles. */
-    y = myrand(map.ysize - 2) + 1; 
-
-    /* Any x-coordinate is valid. */
-    x = myrand(map.xsize);
+    do {
+      rand_pos(&x, &y);
+    } while (y == 0 || y == map.ysize-1);
  
     /* Check if it is suitable to start a river on the current tile.
      */
@@ -721,9 +711,9 @@
 
 
       /* Reset river_map before making a new river. */
-      for (i = 0; i < map.xsize * map.ysize; i++) {
-       river_map[i] = 0;
-      }
+      whole_map_iterate(x, y) {
+       rmap(x, y) = 0;
+      } whole_map_iterate_end;
 
       freelog(LOG_DEBUG,
              "Found a suitable starting tile for a river at (%d, %d)."
@@ -777,17 +767,12 @@
 **************************************************************************/
 static void make_passable(void)
 {
-  int x;
-  
-  for (x=0;x<map.xsize;x++) {
-    map_set_terrain(x, 2, T_OCEAN);
-    if (myrand(100)>50) map_set_terrain(x,1,T_OCEAN);
-    if (myrand(100)>50) map_set_terrain(x,3,T_OCEAN);
-    map_set_terrain(x, map.ysize-3, T_OCEAN);
-    if (myrand(100)>50) map_set_terrain(x,map.ysize-2,T_OCEAN);
-    if (myrand(100)>50) map_set_terrain(x,map.ysize-4,T_OCEAN);
-  } 
-  
+  whole_map_iterate(x, y) {
+    int dist = DISTANCE_FROM_POLE(x, y);
+    if (dist == 2 ||
+        ((dist==1 || dist==3) && myrand(100)>50))
+      map_set_terrain(x, y, T_OCEAN);
+  } whole_map_iterate_end;
 }
 
 /**************************************************************************
@@ -796,10 +781,9 @@
 **************************************************************************/
 static void make_fair(void)
 {
-  int x,y;
-  for (y=2;y<map.ysize-2;y++) {
-    for (x=0;x<map.xsize;x++) {
-      if (terrain_is_clean(x,y)) {
+  whole_map_iterate(x, y) {
+    if (DISTANCE_FROM_POLE(x, y) >= 2 &&
+        terrain_is_clean(x,y)) {
        if (map_get_terrain(x, y) != T_RIVER &&
            !(map_get_special(x, y) & S_RIVER)) {
          map_set_terrain(x, y, T_HILLS);
@@ -812,9 +796,8 @@
            map_set_terrain(x1, y1, T_HILLS);
          }       
        } cartesian_adjacent_iterate_end;
-      }
     }
-  }
+  } whole_map_iterate_end;
 }
 
 /**************************************************************************
@@ -892,7 +875,7 @@
 **************************************************************************/
 static int assign_continent_flood(int x, int y, int nr)
 {
-  if (y<0 || y>=map.ysize)              return 0;
+  assert(is_normal_map_pos(x, y));
   if (map_get_continent(x, y))          return 0;
   if (map_get_terrain(x, y) == T_OCEAN) return 0;
 
@@ -922,10 +905,13 @@
     map_set_continent(x, y, 0);
   } whole_map_iterate_end;
 
+  /* We first label the poles.  This will also work if there's just one pole. 
*/
   if (map.generator != 0) {
-    assign_continent_flood(0, 0, 1);
-    assign_continent_flood(0, map.ysize-1, 2);
-    isle = 3;
+    whole_map_iterate(x, y) {
+      if (DISTANCE_FROM_POLE(x, y) == 0 &&
+         !map_get_continent(x, y) && map_get_terrain(x, y) != T_OCEAN)
+        assign_continent_flood(x, y, isle++);
+    } whole_map_iterate_end;
   }
       
   whole_map_iterate(x, y) {
@@ -1140,8 +1126,7 @@
   assert(game.nplayers<=nr+sum);
 
   while (nr<game.nplayers) {
-    x=myrand(map.xsize);
-    y=myrand(map.ysize); 
+    rand_pos(&x, &y);
     if (islands[(int)map_get_continent(x, y)].starters) {
       j++;
       if (!is_starter_close(x, y, nr, dist)) {
@@ -1309,7 +1294,9 @@
   } whole_map_iterate_end;
 
   for (i=0;i<1500;i++) {
-    height_map[myrand(map.ysize*map.xsize)]+=myrand(5000);
+    int x, y;
+    rand_pos(&x, &y);
+    hmap(x, y) += myrand(5000);
     if (!(i%100)) {
       smooth_map(); 
     }
@@ -1381,8 +1368,7 @@
   int x,y,l;
   int count=0;
   while ((number*map.xsize*map.ysize)/2000 && count++<map.xsize*map.ysize*2) {
-    x=myrand(map.xsize);
-    y=myrand(map.ysize);
+    rand_pos(&x, &y);
     l=myrand(6);
     if (map_get_terrain(x, y)!=T_OCEAN && 
        ( map_get_terrain(x, y)!=T_ARCTIC || l<3 )
@@ -1400,10 +1386,10 @@
 
 static void add_specials(int prob)
 {
-  int x,y;
   enum tile_terrain_type ttype;
-  for (y=1;y<map.ysize-1;y++) {
-    for (x=0;x<map.xsize; x++) {
+
+  whole_map_iterate(x, y) {
+    if (DISTANCE_FROM_POLE(x, y) > 0) {
       ttype = map_get_terrain(x, y);
       if ((ttype==T_OCEAN && is_coastline(x,y)) || (ttype!=T_OCEAN)) {
        if (myrand(1000)<prob) {
@@ -1419,7 +1405,7 @@
        }
       }
     }
-  }
+  } whole_map_iterate_end;
   map.have_specials = 1;
 }
 
@@ -1545,8 +1531,7 @@
 static int place_island(void)
 {
   int x, y, xo, yo, i=0;
-  yo = myrand(map.ysize);
-  xo = myrand(map.xsize);
+  rand_pos(&xo, &yo);
 
   /* this helps a lot for maps with high landmass */
   for (y = n, x = w ; y < s && x < e ; y++, x++) {
@@ -1756,30 +1741,23 @@
 **************************************************************************/
 static void initworld(void)
 {
-  int x, y;
-  
   height_map = fc_malloc(sizeof(int) * map.ysize * map.xsize);
   islands = fc_malloc((MAP_NCONT+1)*sizeof(struct isledata));
-  
-  for (y = 0 ; y < map.ysize ; y++) 
-    for (x = 0 ; x < map.xsize ; x++) {
+
+  whole_map_iterate(x, y) {
       map_set_terrain(x, y, T_OCEAN);
       map_set_continent(x, y, 0);
-    }
-  for (x = 0 ; x < map.xsize; x++) {
-    map_set_terrain(x, 0, myrand(9) ? T_ARCTIC : T_TUNDRA);
-    map_set_continent(x, 0, 1);
-    if (!myrand(9)) {
-      map_set_terrain(x, 1, myrand(9) ? T_TUNDRA : T_ARCTIC);
-      map_set_continent(x, 1, 1);
-    }
-    map_set_terrain(x, map.ysize-1, myrand(9) ? T_ARCTIC : T_TUNDRA);
-    map_set_continent(x, map.ysize-1, 2);
-    if (!myrand(9)) {
-      map_set_terrain(x, map.ysize-2, myrand(9) ? T_TUNDRA : T_ARCTIC);
-      map_set_continent(x, map.ysize-2, 2);
+  } whole_map_iterate_end;
+
+  whole_map_iterate(x, y) {
+    if (DISTANCE_FROM_POLE(x, y) == 0 ||
+       (!myrand(9) && DISTANCE_FROM_POLE(x, y) == 1)) {
+      int antarctic = DISTANCE_FROM_NORTH_POLE(x, y) > 
DISTANCE_FROM_SOUTH_POLE(x, y);
+      map_set_terrain(x, y, myrand(9) ? T_ARCTIC : T_TUNDRA);
+      map_set_continent(x, y, 1 + antarctic);
     }
-  }
+  } whole_map_iterate_end;
+
   map.num_continents = 2;
   make_island(0, 0);
   islands[2].starters = 0;
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.87
diff -u -r1.87 maphand.c
--- server/maphand.c    2001/10/11 12:37:06     1.87
+++ server/maphand.c    2001/10/19 18:37:13
@@ -75,8 +75,7 @@
 
   k = map.xsize * map.ysize;
   while(effect && k--) {
-    x = myrand(map.xsize);
-    y = myrand(map.ysize);
+    rand_pos(&x, &y);
     if (map_get_terrain(x, y) != T_OCEAN) {
       if (is_terrain_ecologically_wet(x, y)) {
        switch (map_get_terrain(x, y)) {
@@ -132,8 +131,7 @@
 
   k =map.xsize * map.ysize;
   while(effect && k--) {
-    x = myrand(map.xsize);
-    y = myrand(map.ysize);
+    rand_pos(&x, &y);
     if (map_get_terrain(x, y) != T_OCEAN) {
       switch (map_get_terrain(x, y)) {
       case T_JUNGLE:

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