? fractalgenerator.diff Index: common/map.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/map.h,v retrieving revision 1.125 diff -u -r1.125 map.h --- common/map.h 2002/02/27 10:33:08 1.125 +++ common/map.h 2002/05/26 17:44:04 @@ -637,7 +637,7 @@ #define MAP_DEFAULT_GENERATOR 1 #define MAP_MIN_GENERATOR 1 -#define MAP_MAX_GENERATOR 4 +#define MAP_MAX_GENERATOR 5 #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.95 diff -u -r1.95 mapgen.c --- server/mapgen.c 2002/05/14 19:40:41 1.95 +++ server/mapgen.c 2002/05/26 17:44:09 @@ -40,6 +40,7 @@ static void mapgenerator2(void); static void mapgenerator3(void); static void mapgenerator4(void); +static void mapgenerator5(void); static void smooth_map(void); static void adjust_map(int minval); @@ -908,7 +909,7 @@ map.generator != 0; otherwise are not special. Also sets map.num_continents (note 0 is ocean, and continents have numbers 1 to map.num_continents _inclusive_). - Note this is not used by generators>1 at map creation + Note this is not used by generators 2,3 or 4 at map creation time, as these assign their own continent numbers. **************************************************************************/ void assign_continent_numbers(void) @@ -1121,7 +1122,7 @@ int x, y, j=0, k, sum; int counter = 0; - if (!islands) /* already setup for generator>1 */ + if (!islands) /* already setup for generators 2,3,4 */ setup_isledata(); if(dist>= map.xsize/2) @@ -1195,6 +1196,8 @@ map_allocate(); /* if one mapgenerator fails, it will choose another mapgenerator */ /* with a lower number to try again */ + if (map.generator == 5 ) + mapgenerator5(); if (map.generator == 4 ) mapgenerator4(); if (map.generator == 3 ) @@ -2051,4 +2054,118 @@ if(checkmass>map.xsize+map.ysize+totalweight) { freelog(LOG_VERBOSE, "%ld mass left unplaced", checkmass); } +} + +/************************************************************************** +Recursive function which does the work for generator 5 +**************************************************************************/ +static void gen5rec(int step, int x0, int y0, int x1, int y1){ + int val[2][2]; + int x1wrap = x1; /* to wrap correctly */ + int y1wrap = y1; + + if ((y1-y0 <= 0) || (x1-x0 <= 0)){ + return; + } + + if (x1 == map.xsize) + x1wrap = 0; + if (y1 == map.ysize) + y1wrap = 0; + + val[0][0] = hmap(x0,y0); + val[0][1] = hmap(x0,y1wrap); + val[1][0] = hmap(x1wrap,y0); + val[1][1] = hmap(x1wrap,y1wrap); + + /* set midpoints of sides to avg of side's vertices plus a random factor */ + /* unset points are zero, don't reset if set */ + if (hmap((x0+x1)/2, y0) == 0) + hmap((x0+x1)/2, y0) = (val[0][0] + val[1][0])/2 + myrand(step) - step/2; + if (hmap((x0+x1)/2, y1wrap) == 0) + hmap((x0+x1)/2, y1wrap) = (val[0][1] + val[1][1])/2 + myrand(step)- step/2; + if (hmap(x0, (y0+y1)/2) == 0) + hmap(x0, (y0+y1)/2) = (val[0][0] + val[0][1])/2 + myrand(step) - step/2; + if (hmap(x1wrap, (y0+y1)/2) == 0) + hmap(x1wrap, (y0+y1)/2) = (val[1][0] + val[1][1])/2 + myrand(step)- step/2; + + /* noone could have set the middle yet */ + /* set middle to average of midpoints plus a random factor */ + hmap((x0+x1)/2, (y0+y1)/2) = + (val[0][0] + val[0][1] + val[1][0] + val[1][1])/4 + myrand(step) - step/2; + + if ((y1-y0 == 1) && (x1-x0 == 1)){ + return; + } + gen5rec(2*step/3, x0, y0, (x1 + x0) / 2, (y1 + y0) / 2); + gen5rec(2*step/3, x0, (y1 + y0) / 2, (x1 + x0) / 2, y1); + gen5rec(2*step/3, (x1 + x0) / 2, y0, x1, (y1 + y0) / 2); + gen5rec(2*step/3, (x1 + x0) / 2, (y1 + y0) / 2, x1, y1); +} + +/************************************************************************** +This generator makes earthlike worlds with one or more large continents and +a scattering of smaller islands. It does so by dividing the world into +blocks and on each block raising or lowering the corners, then the +midpoints and middle and so on recursively. Fiddling with 'xdiv' and +'ydiv', and, if the map does not wrap in at least one direction, 'avoidedge' +will vary the result. +**************************************************************************/ +static void mapgenerator5(void){ + int x, y; + int xnowrap = 0; /* could come from topology */ + int ynowrap = 1; /* could come from topology */ + int xmax = map.xsize - xnowrap; + int ymax = map.ysize - ynowrap; + int xdiv = 4; /* how many blocks should the x and y directions be */ + int ydiv = 3; /* divided into initially */ + int avoidedge = 10; /* edges are avoided more strongly as this increases */ + int minval = 0; + int step = map.xsize + map.ysize; + /* just need something > log(max(xsize, ysize)) for the recursion */ + + height_map=fc_malloc (sizeof(int)*map.xsize*map.ysize); + + adjust_terrain_param(); + + /* initialize map */ + whole_map_iterate(x, y){ + hmap(x, y) = 0; + }whole_map_iterate_end; + + /* set initial points */ + for (x=0; x < xdiv+xnowrap; x++) + for (y=0; y < ydiv+ynowrap; y++) + hmap(x*xmax/xdiv, y*ymax/ydiv) = myrand(2*step) - (2*step)/2; + /* if we aren't wrapping stay away from edges to some extent */ + if (xnowrap) + for (y=0; y< ydiv+ynowrap; y++){ + hmap(0, y*ymax/ydiv) -= avoidedge; + hmap(xmax, y*ymax/ydiv) -= avoidedge; + } + if (ynowrap) + for (x=0; x< xdiv+xnowrap; x++){ + hmap(x*xmax/xdiv, 0) -= avoidedge; + hmap(x*xmax/xdiv, ymax) -= avoidedge; + } + + /* calculate recursively on each block */ + for (x=0; x maxval) + maxval = hmap(x, y); + if (hmap(x, y) < minval) + minval = hmap(x, y); + }whole_map_iterate_end; + maxval-=minval; + adjust_map(minval); + + make_land(); + free(height_map); } Index: server/stdinhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v retrieving revision 1.228 diff -u -r1.228 stdinhand.c --- server/stdinhand.c 2002/05/25 17:44:09 1.228 +++ server/stdinhand.c 2002/05/26 17:44:17 @@ -234,6 +234,7 @@ " with three players for an odd number of players), and " "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) " "maps.\n" "(Zero indicates a scenario map.)"), NULL,