Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2003:
[Freeciv-Dev] Patch to shorten games
Home

[Freeciv-Dev] Patch to shorten games

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Patch to shorten games
From: Josh Cogliati <jjc@xxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 10 Mar 2003 21:53:28 -0600
Reply-to: freeciv-dev@xxxxxxxxxxx

Have you ever wished that you could get into the action sooner in 
a freeciv game?  Ever get tired of spending fifteen minutes playing 
freeciv solitary before you meet the other players?

Well, this patch (http://rt.freeciv.org/Ticket/Display.html?id=3489)
is the patch for you.  It adds a new generator 6 that creates a world that
looks about like this (# = roads, + = player starting positions, * = land):
************************
########################
**#** *****  ******
 *#*   *+**   *+**
 *#*
**#**  *+*    *+**
**#*  *****  *****
########################
************************
Basically it generates a central sea surrounded by peninsula's for each 
of the players, a isthmus to connect the north and south poles,
and handy prebuilt roads to speed your troops and settlers 
around the globe

For your patching pleasure (generated against cvs from just minutes ago)
here it is:
--
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.140
diff -u -r1.140 map.h
--- common/map.h        2003/02/20 09:45:21     1.140
+++ common/map.h        2003/03/11 03:31:14
@@ -632,7 +632,7 @@
 
 #define MAP_DEFAULT_GENERATOR    1
 #define MAP_MIN_GENERATOR        1
-#define MAP_MAX_GENERATOR        5
+#define MAP_MAX_GENERATOR        6
 
 #define MAP_DEFAULT_TINYISLES    FALSE
 #define MAP_MIN_TINYISLES        FALSE
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.110
diff -u -r1.110 mapgen.c
--- server/mapgen.c     2003/02/20 09:45:22     1.110
+++ server/mapgen.c     2003/03/11 03:31:38
@@ -42,6 +42,7 @@
 static void mapgenerator3(void);
 static void mapgenerator4(void);
 static void mapgenerator5(void);
+static void mapgenerator6(void);
 static void smooth_map(void);
 static void adjust_map(int minval);
 
@@ -1157,6 +1158,8 @@
     map_allocate();
     /* if one mapgenerator fails, it will choose another mapgenerator */
     /* with a lower number to try again */
+    if (map.generator == 6 )
+      mapgenerator6();
     if (map.generator == 5 )
       mapgenerator5();
     if (map.generator == 4 )
@@ -2139,4 +2142,263 @@
   make_land();
   free(height_map);
   height_map = NULL;
+}
+
+static int land_terrain(int x, int y)
+{
+  return !is_ocean(map_get_terrain(x,y));
+}
+
+static int border_score(int x, int y)
+{
+  int adj_score = 2;
+  int diag_score = 1;
+  int score = 0;
+  score += land_terrain(x-1,y) ? adj_score : 0;
+  score += land_terrain(x+1,y) ? adj_score : 0;
+  score += land_terrain(x,y-1) ? adj_score : 0;
+  score += land_terrain(x,y+1) ? adj_score : 0;
+  score += land_terrain(x-1,y-1) ? diag_score : 0;
+  score += land_terrain(x+1,y-1) ? diag_score : 0;
+  score += land_terrain(x-1,y+1) ? diag_score : 0;
+  score += land_terrain(x+1,y+1) ? diag_score : 0;
+  return score;
+}
+
+static int random_new_land(int x, int y)
+{
+  int score;
+  int random;
+  if(land_terrain(x, y)) {
+    return T_PLAINS;
+  }
+  score = border_score(x, y);
+  random = myrand(4*2+4*1);
+  return random + 1 > score  ? T_OCEAN : T_GRASSLAND;
+  
+}
+
+/* Creates a peninsula and put the player's starting position
+   on it */
+static void create_peninsula(int x, int y,int player_number,
+                            int width, int height,int direction,
+                            int remaining_count)
+{
+  int cx, cy;
+
+  cx = x+width/2;
+  for(cy = y; cy != y + (height + 1)*direction; 
+      cy += direction) {
+    map_set_terrain(cx, cy, T_GRASSLAND);
+    map_set_continent(cx, cy, 1);
+  }
+  remaining_count -= height; /* account for the already added strip */
+  cy = y;
+  for(cx = x + width/2 - 2; cx <= x + width/2 + 2; cx ++) {
+    map_set_terrain(cx, cy, T_GRASSLAND);
+    map_set_continent(cx, cy, 1);    
+  }
+  remaining_count -= 4; /* account for extra 4 (not 5 because that would 
+                       double count the one already done by height strip.*/
+  
+  while (remaining_count > 0) {
+    for(cx = x; cx < x+width; cx++) {
+      for(cy = y; cy != y + (height + 1)*direction; cy += direction) {
+       int new_terrain = random_new_land(cx, cy);
+       if(new_terrain == T_GRASSLAND){
+         remaining_count--;
+         map_set_terrain(cx, cy, T_GRASSLAND);
+         map_set_continent(cx, cy, 1);
+         hmap(cx, cy) = 20 * (cx - x) * (width - (cx - x)) + myrand(80) - 40;
+       }
+       if(remaining_count <= 0) {
+         goto done_with_peninsula;
+       }
+      }
+    }
+  }
+
+ done_with_peninsula:
+
+  map.start_positions[player_number].x = x+width/2;
+  map.start_positions[player_number].y = y;
+}
+
+/* This generator creates a map with one penisula for each 
+   player and an isthmus between.  It creates a central
+   ocean and puts the peninsulas around the edges.  It is 
+   intented for quicker games. Should look something like this:
+   *****************************
+   **  *****  *****  *****    ** 
+   *    ***    ***    ***      *
+   *                           *
+   *                           *
+   *    ***    ***             *
+   **  *****  *****           **
+   *****************************
+ */
+static void mapgenerator6(void)
+{
+  int peninsulas = game.nplayers;
+  int peninsulas_on_one_side = (peninsulas + 1)/2;
+  int isthmus_width = 10;
+  int peninsula_separation = 5;
+  int peninsula_width = 
+    (map.xsize - isthmus_width - peninsula_separation)
+      /(peninsulas_on_one_side) - peninsula_separation;
+  /* if landpercent <= 50, then make shorter peninsulas */
+  int peninsula_height = (map.landpercent <= 50) 
+    ? map.ysize/3
+      : (map.ysize*2)/5;
+  int continent_percent = (map.landpercent <= 50) 
+    ? (map.landpercent * 3)/2 
+      : (map.landpercent * 5)/4;
+  int i, x, y;
+  int polar_height = 3;
+  int remaining_count = 
+    MIN(isthmus_width * (map.ysize - polar_height*2),
+       ((isthmus_width+peninsula_separation) * (map.ysize - polar_height*2) 
+        * continent_percent)/100);
+ 
+  height_map = fc_malloc(sizeof(int) * map.xsize * map.ysize);
+
+  /* initialize everything to ocean */
+  for (y = 0 ; y < map.ysize ; y++) 
+    for (x = 0 ; x < map.xsize ; x++) {
+      map_set_terrain(x, y, T_OCEAN);
+      map_set_continent(x, y, 0);
+      hmap(x, y) = 0;
+    }
+
+  /* create polar regions */
+  for (x = 0 ; x < map.xsize; x++) {
+    for (y = 0; y < polar_height; y++) {
+      int rand_num = myrand(9);
+      map_set_terrain(x, y, rand_num > 7 ? T_ARCTIC :
+                     (rand_num < 2 ? T_MOUNTAINS : T_TUNDRA));
+      map_set_continent(x, y, 1);
+      rand_num = myrand(9);
+      map_set_terrain(x, map.ysize-1-y, rand_num > 7 ? T_ARCTIC :
+                     (rand_num < 2 ? T_MOUNTAINS : T_TUNDRA));
+      map_set_continent(x, map.ysize-1-y, 1);
+    }
+  }
+  
+  /* build polar regions road */
+  for (x = 0 ; x < map.xsize; x++) {
+         y = polar_height-1;
+         if(map_build_road_time(x,y-1) < map_build_road_time(x,y))
+         {
+                 map_set_special(x,y-1,S_ROAD);
+         } else {
+                 map_set_special(x,y,S_ROAD);
+         }
+         y = map.ysize-polar_height;
+         if(map_build_road_time(x,y+1) < map_build_road_time(x,y))
+         {
+                 map_set_special(x,y+1,S_ROAD);
+         } else {
+                 map_set_special(x,y,S_ROAD);
+         }
+  }
+
+  map.num_continents = 1;
+
+  /* create isthmus centeral strip */
+  x = isthmus_width/2;
+  for (y = polar_height; y < map.ysize - polar_height; y++) {
+    map_set_terrain(x, y, T_GRASSLAND);
+    map_set_continent(x, y, 1);
+    hmap(x, y) = 100 * x * (isthmus_width - x) + (myrand(400) - 200);
+  }
+
+  remaining_count -= (map.ysize - 2*polar_height) * 1;
+
+  /* add additional isthmus area randomly */
+  while(remaining_count > 0) {
+    for (y = polar_height; y < map.ysize/2; y++) {
+      for (x = 0; x < isthmus_width; x++) {
+       int new_terrain = random_new_land(x, y);
+       if(new_terrain == T_GRASSLAND){
+         remaining_count--;
+         map_set_terrain(x, y, T_GRASSLAND);
+         map_set_continent(x, y, 1);
+         hmap(x, y) = 100 * x * (isthmus_width - x) + (myrand(400) - 200);
+       }
+       if(remaining_count <= 0) {
+         goto done_with_isthmus;
+       }
+      }
+    }
+    
+    for (y = map.ysize - polar_height - 1; y >= map.ysize/2; y--) {
+      for (x = 0; x < isthmus_width; x++) {
+       int new_terrain = random_new_land(x, y);
+       if(new_terrain == T_GRASSLAND){
+         remaining_count--;
+         map_set_terrain(x, y, T_GRASSLAND);
+         map_set_continent(x, y, 1);
+         hmap(x, y) = 100 * x * (isthmus_width - x) + (myrand(400) - 200);
+       }
+       if(remaining_count <= 0) {
+         goto done_with_isthmus;
+       }
+      }
+    }
+  }
+ done_with_isthmus:
+  
+  /* setup peninsulas */
+  for(i = 0; i < game.nplayers; i++) {
+    /* direction is the direction to increment from the x and y location */
+    int direction = (i < peninsulas_on_one_side) ? -1 : 1;
+    int index = (direction == -1) ? i : i - peninsulas_on_one_side;
+    int width = (continent_percent < 95) 
+      ? peninsula_width
+       : peninsula_width + peninsula_separation - 1;/*Give more room */
+    int height = peninsula_height-polar_height;
+    int peninsula_remaining_count = 
+      MIN(width*height,
+         ((width+peninsula_separation)*height*continent_percent)/100);
+    x = index * (peninsula_width + peninsula_separation) 
+      + isthmus_width + peninsula_separation;
+    y = (direction == -1) 
+      ? peninsula_height 
+       : map.ysize - 1 - peninsula_height;
+    create_peninsula(x,y,i,width,height,direction,peninsula_remaining_count);
+  }
+
+  map.num_start_positions = game.nplayers;
+  
+  /* setup terrain */
+  make_mountains(1600);
+  make_swamps();
+  make_forests();
+  make_deserts();
+  make_plains();
+  make_fair();
+  make_rivers();
+
+  /* create isthmus road */
+  {
+    int last_x, middle_x = isthmus_width/2;
+    last_x = middle_x;
+    for (y = polar_height - 1; y < map.ysize - polar_height + 1; y++) {
+      int best_x = middle_x;
+      int min_build = 100;
+      for(x = MAX(last_x - 1, middle_x - 1);
+         x != MIN(last_x + 1,middle_x + 1) + 1; x++) {
+       if(land_terrain(x,y) && map_build_road_time(x,y) < min_build) {
+         best_x = x;
+         min_build = map_build_road_time(x,y);
+       }
+      }
+      map_set_special(best_x,y,S_ROAD);
+      last_x = best_x;
+    }
+  }
+  
+
+  free(height_map);
+       
 }
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.272
diff -u -r1.272 stdinhand.c
--- server/stdinhand.c  2003/03/10 16:34:50     1.272
+++ server/stdinhand.c  2003/03/11 03:32:01
@@ -241,7 +241,9 @@
        "additional\n"
        "    smaller islands.\n"
        "5 = one or more large earthlike continents with some scatter.\n"
-       "Note: values 2,3 and 4 generate \"fairer\" (but more boring) "
+       "6 = equally sized peninsulas with one player each surrounding  \n"
+       "    an inland sea.\n"
+       "Note: values 2,3,4 and 6 generate \"fairer\" (but more boring) "
        "maps.\n"
        "(Zero indicates a scenario map.)"), NULL,
          MAP_MIN_GENERATOR, MAP_MAX_GENERATOR, MAP_DEFAULT_GENERATOR)

-- 
Josh Cogliati



[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] Patch to shorten games, Josh Cogliati <=