Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2005:
[Freeciv-Dev] (PR#13596) pubserver crash when creating start positions
Home

[Freeciv-Dev] (PR#13596) pubserver crash when creating start positions

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] (PR#13596) pubserver crash when creating start positions
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Fri, 5 Aug 2005 00:51:27 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13596 >

> [mstefek - Thu Aug 04 08:05:13 2005]:
> 
> > [jdorje - Thu Aug 04 03:18:11 2005]:
> > 
> > The attached autogame reproduces the problem for S2_0 from "Thu Aug  4 
> > 03:17:42 UTC 2005" (and probably 2.0.4 also).
> > 
> > -jason
> 
> There are anough continents, but many of them are 1x1 glacier. Their
> value is 0.
> 
> This patch adds simple fallback machanism to create_start_positions.
> 
One more case when MT_ALL fails and a HEAD version.
--
matuesz
Index: server/generator/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/mapgen.c,v
retrieving revision 1.31
diff -u -r1.31 mapgen.c
--- server/generator/mapgen.c   4 Aug 2005 15:47:12 -0000       1.31
+++ server/generator/mapgen.c   5 Aug 2005 07:45:44 -0000
@@ -1207,26 +1207,53 @@
   /* We don't want random start positions in a scenario which already
    * provides them. */
   if (map.num_start_positions == 0) {
+    enum start_mode mode = MT_ALL;
+    bool success;
+    
     switch (map.generator) {
     case 0:
     case 1:
-      create_start_positions(map.startpos);
+      mode = map.startpos;
       break;
     case 2:
       if (map.startpos == 0) {
-       create_start_positions(MT_ALL);
+        mode = MT_ALL;
       } else {
-       create_start_positions(map.startpos);
+        mode = map.startpos;
       }
       break;
     case 3:
       if (map.startpos <= 1 || (map.startpos == 4)) {
-       create_start_positions(MT_SINGLE);
+        mode = MT_SINGLE;
       } else {
-       create_start_positions(MT_2or3);
+       mode = MT_2or3;
       }
       break;
     }
+    
+    for(;;) {
+      success = create_start_positions(mode);
+      if (success) {
+        break;
+      }
+      
+      switch(mode) {
+        case MT_SINGLE:
+         mode = MT_2or3;
+         break;
+       case MT_2or3:
+         mode = MT_ALL;
+         break;
+       case MT_ALL:
+         mode = MT_VARIABLE;
+         break;
+       default:
+         assert(0);
+         die("The server couldn't allocate starting positions.");
+      }
+    }
+
+
   }
 
   assign_continent_numbers(FALSE);
Index: server/generator/startpos.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/startpos.c,v
retrieving revision 1.15
diff -u -r1.15 startpos.c
--- server/generator/startpos.c 14 Jul 2005 19:25:47 -0000      1.15
+++ server/generator/startpos.c 5 Aug 2005 07:45:44 -0000
@@ -181,8 +181,10 @@
   MT_2or3: 2 players per isle (maybe one isle with 3)
   MT_ALL: all players in asingle isle
   MT_VARIABLE: at least 2 player per isle
+  
+  Returns true on success
 **************************************************************************/
-void create_start_positions(enum start_mode mode)
+bool create_start_positions(enum start_mode mode)
 {
   struct tile *ptile;
   int k, sum;
@@ -192,6 +194,7 @@
   int total_goodies = 0;
   /* this is factor is used to maximize land used in extreme little maps */
   float efactor =  game.info.nplayers / map.size / 4; 
+  bool failure = FALSE;
 
   /* Unsafe terrains separate continents, otherwise small areas of green
    * near the poles could be populated by a civilization if that pole
@@ -355,10 +358,13 @@
     } else {
       data.min_value *= 0.9;
       if (data.min_value <= 10) {
-       die(_("The server appears to have gotten into an infinite loop "
-             "in the allocation of starting positions, and will abort.\n"
-             "Maybe the numbers of players/ia is too much for this map.\n"
-             "Please report this bug at %s."), WEBSITE_URL);
+       freelog(LOG_ERROR,
+               _("The server appears to have gotten into an infinite loop "
+                 "in the allocation of starting positions.\n"
+                 "Maybe the numbers of players/ia is too much for this map.\n"
+                 "Please report this bug at %s."), WEBSITE_URL);
+       failure = TRUE;
+       break;
       }
     }
   }
@@ -368,4 +374,6 @@
   free(islands_index);
   islands = NULL;
   islands_index = NULL;
+  
+  return !failure;
 }
Index: server/generator/startpos.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/startpos.h,v
retrieving revision 1.3
diff -u -r1.3 startpos.h
--- server/generator/startpos.h 25 Mar 2005 11:25:09 -0000      1.3
+++ server/generator/startpos.h 5 Aug 2005 07:45:44 -0000
@@ -21,6 +21,6 @@
   MT_VARIABLE
 };
 
-void create_start_positions(enum start_mode mode);
+bool create_start_positions(enum start_mode mode);
 
 #endif
Index: server/generator/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/mapgen.c,v
retrieving revision 1.12.2.7
diff -u -r1.12.2.7 mapgen.c
--- server/generator/mapgen.c   21 Jul 2005 19:32:05 -0000      1.12.2.7
+++ server/generator/mapgen.c   5 Aug 2005 07:41:59 -0000
@@ -1102,26 +1102,53 @@
   /* We don't want random start positions in a scenario which already
    * provides them. */
   if (map.num_start_positions == 0) {
+    enum start_mode mode = MT_ALL;
+    bool success;
+    
     switch (map.generator) {
     case 0:
     case 1:
-      create_start_positions(map.startpos);
+      mode = map.startpos;
       break;
     case 2:
       if (map.startpos == 0) {
-       create_start_positions(MT_ALL);
+        mode = MT_ALL;
       } else {
-       create_start_positions(map.startpos);
+        mode = map.startpos;
       }
       break;
     case 3:
       if (map.startpos <= 1 || (map.startpos == 4)) {
-       create_start_positions(MT_SINGLE);
+        mode = MT_SINGLE;
       } else {
-       create_start_positions(MT_2or3);
+       mode = MT_2or3;
       }
       break;
     }
+    
+    for(;;) {
+      success = create_start_positions(mode);
+      if (success) {
+        break;
+      }
+      
+      switch(mode) {
+        case MT_SINGLE:
+         mode = MT_2or3;
+         break;
+       case MT_2or3:
+         mode = MT_ALL;
+         break;
+       case MT_ALL:
+         mode = MT_VARIABLE;
+         break;
+       default:
+         assert(0);
+         die("The server couldn't allocate starting positions.");
+      }
+    }
+
+
   }
 
   assign_continent_numbers(FALSE);
Index: server/generator/startpos.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/startpos.c,v
retrieving revision 1.3.2.3
diff -u -r1.3.2.3 startpos.c
--- server/generator/startpos.c 8 Nov 2004 15:17:54 -0000       1.3.2.3
+++ server/generator/startpos.c 5 Aug 2005 07:41:59 -0000
@@ -177,8 +177,10 @@
   MT_2or3: 2 players per isle (maybe one isle with 3)
   MT_ALL: all players in asingle isle
   MT_VARIABLE: at least 2 player per isle
+  
+  Returns true on success
 **************************************************************************/
-void create_start_positions(enum start_mode mode)
+bool create_start_positions(enum start_mode mode)
 {
   struct tile *ptile;
   int k, sum;
@@ -188,6 +190,7 @@
   int total_goodies = 0;
   /* this is factor is used to maximize land used in extreme little maps */
   float efactor =  game.nplayers / map.size / 4; 
+  bool failure = FALSE;
 
   /* Unsafe terrains separate continents, otherwise small areas of green
    * near the poles could be populated by a civilization if that pole
@@ -351,10 +354,13 @@
     } else {
       data.min_value *= 0.9;
       if (data.min_value <= 10) {
-       die(_("The server appears to have gotten into an infinite loop "
-             "in the allocation of starting positions, and will abort.\n"
-             "Maybe the numbers of players/ia is too much for this map.\n"
-             "Please report this bug at %s."), WEBSITE_URL);
+       freelog(LOG_ERROR,
+               _("The server appears to have gotten into an infinite loop "
+                 "in the allocation of starting positions.\n"
+                 "Maybe the numbers of players/ia is too much for this map.\n"
+                 "Please report this bug at %s."), WEBSITE_URL);
+       failure = TRUE;
+       break;
       }
     }
   }
@@ -364,4 +370,6 @@
   free(islands_index);
   islands = NULL;
   islands_index = NULL;
+  
+  return !failure;
 }
Index: server/generator/startpos.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/generator/startpos.h,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 startpos.h
--- server/generator/startpos.h 15 Oct 2004 09:39:36 -0000      1.1.2.1
+++ server/generator/startpos.h 5 Aug 2005 07:41:59 -0000
@@ -21,6 +21,6 @@
   MT_VARIABLE
 };
 
-void create_start_positions(enum start_mode mode);
+bool create_start_positions(enum start_mode mode);
 
 #endif

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