This patch is designed to be in used with the best.islands.patch.

What this patch does is simple: It makes sure that each player gets
their own island, and that each island only gets one player.  No
one is allowed to be on the polar islands; all of the other islands
will have a player on them if the island can fit the player.

In the case of there being more islands than players, only the 
best islands will be filled.  In the case of their being more players
than islands, the players which exceed the island count will be
discarded.

- Sam

--- freeciv-1.14.0/server/mapgen.c.orig	Mon Mar 24 21:45:26 2003
+++ freeciv-1.14.0/server/mapgen.c	Mon Mar 24 23:47:41 2003
@@ -64,6 +64,7 @@
   int x,y;                        /* upper left corner of the islands */
   int goodies;
   int starters;
+  int continent;
 };
 static struct isledata *islands;
 
@@ -975,6 +976,7 @@
   for(i=0; i<=map.num_continents; i++) {
     islands[i].x = islands[i].y = -1;             /* flag */
     islands[i].goodies = islands[i].starters = 0;
+    islands[i].continent = 0;
   }
 
   /* get x and y positions: (top left) */
@@ -983,6 +985,7 @@
     if (islands[cont].x == -1) {
       islands[cont].x = x;
       islands[cont].y = y;
+      islands[cont].continent = cont;
     }
   } whole_map_iterate_end;
 
@@ -1075,8 +1078,8 @@
  
       /* starters are loosers */
       for (x=firstcont;x<isles;x++) {
-	if (( islands[x].goodies*4 > 3*(riches+oldisles-1)/oldisles )
-	    &&!(islands[x].goodies > (riches+oldisles-1)/oldisles)) {
+	if (1 == 1) { /* All islands get a starter since we give the
+	                 humans the best islands */
 	  freelog(LOG_VERBOSE, "islands[x].goodies=%i",islands[x].goodies);
 	  islands[x].starters= (islands[x].goodies+guard1)/mingood; 
 	  if(islands[x].starters == 0) {
@@ -1090,7 +1093,7 @@
     /* starters are winners */
     for (x=firstcont;x<isles;x++) {
       if (islands[x].goodies > (riches+oldisles-1)/oldisles) {
-	assert(islands[x].starters == 0);
+	/*assert(islands[x].starters == 0);*/
 	freelog(LOG_VERBOSE, "islands[x].goodies=%i", islands[x].goodies);
 	islands[x].starters = (islands[x].goodies+guard1)/mingood; 
 	if(islands[x].starters == 0) {
@@ -1120,6 +1123,40 @@
 }
 
 /**************************************************************************
+ Comparison function that compares the continent number on two isles
+ *************************************************************************/
+
+static int compar_isle_cont(const void *a,const void *b) 
+{
+
+  struct isledata *t;
+  int ia, ib;
+  t = (struct isledata *)a;
+  ia = t->continent;
+  t = (struct isledata *)b;
+  ib = t->continent;
+  return ia - ib;
+
+}
+
+/**************************************************************************
+ Comparison function that compares the goodies on two isles
+ *************************************************************************/
+
+static int compar_isle_goodies(const void *a,const void *b) 
+{
+
+  struct isledata *t;
+  int ia, ib;
+  t = (struct isledata *)a;
+  ia = t->goodies;
+  t = (struct isledata *)b;
+  ib = t->goodies;
+  return ib - ia;
+
+}
+
+/**************************************************************************
  Comparison function that compares the goodness of two start points (how
  good the island the two start points are on
  *************************************************************************/
@@ -1169,21 +1206,67 @@
      gets their own island; dist is the minimum distance that two players
      can be from one another on the same island */
 
+  dist = 10000000;
+
+
   sum=0;
   for (k=0; k<=map.num_continents; k++) {
-    sum += islands[k].starters;
-    if (islands[k].starters!=0) {
-      freelog(LOG_VERBOSE, "starters on isle %i", k);
-    }
+    sum++;
+    if((k>2 || !map.separatepoles) && k>0) {
+        islands[k].starters = 1;
+	}
+    else {
+        islands[k].starters = 0;
+	}
   }
+
+  if(game.nplayers > map.num_continents - 2) {
+      printf("Sorry, you have too many players.  Discarding some.\n");
+      game.nplayers = map.num_continents - 2;
+      printf("You now only have %d players\n",game.nplayers);
+      }
+
+  /* Sort things so that the best islands come before the bad islands */
+  qsort(&islands[1],map.num_continents,
+        sizeof(struct isledata),compar_isle_goodies);
+
+  /* And now, set starters appropriately so that, when there are
+     more islands than starters, the players always start on the
+     best islands, one island per player (and, with the other patch,
+     the humans get first nibs at the good islands) */
+  sum = 0;
+  for (k=0; k<=map.num_continents; k++) {
+    if(islands[k].starters == 1) {
+        sum++;
+        islands[k].starters = sum;
+	}
+  }
+
+  /* Since code assumes that islands[i] is the same as what map_get_continent
+     returns, re-sort to make this assumption true again */
+  qsort(&islands[1],map.num_continents,
+        sizeof(struct isledata),compar_isle_cont);
+
   assert(game.nplayers<=nr+sum);
 
   while (nr<game.nplayers) {
+    int isle_num;
     rand_map_pos(&x, &y);
-    if (islands[(int)map_get_continent(x, y)].starters != 0) {
+    isle_num = (int)map_get_continent(x, y);
+    if (islands[isle_num].starters <= game.nplayers
+        && islands[isle_num].starters > 0) {
       j++;
-      if (!is_starter_close(x, y, nr, dist)) {
-	islands[(int)map_get_continent(x, y)].starters--;
+      if(counter > 100000 && !map_has_special(x, y, S_HUT) && 
+         (map_get_continent(x, y) > 2 || !map.separatepoles) &&
+	 land_terrain(x,y)) {
+	islands[isle_num].starters = 0;
+	map.start_positions[nr].x=x;
+	map.start_positions[nr].y=y;
+	nr++;
+	}
+      else if (!is_starter_close(x, y, nr, 1000000) && land_terrain(x, y)
+        && (map_get_continent(x, y) > 2 || !map.separatepoles)) {
+	islands[isle_num].starters = 0;
 	map.start_positions[nr].x=x;
 	map.start_positions[nr].y=y;
 	nr++;
