[Freeciv-Dev] Re: Make gen2 fair (PR#4659)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
On Thu, Sep 18, 2003 at 05:28:11PM +0100, Gregory Berkolaiko wrote:
> On Thu, 18 Sep 2003, Cameron J. Morland wrote:
>
> > On Thu, Sep 18, 2003 at 02:13:48PM +0100, Gregory Berkolaiko wrote:
> > > How about using bigfrac > medfrac for the while loop? Is it a good idea?
> >
> > That would make some sense; I'll try to create an updated patch this
> > afternoon if you like.
>
> I would do it myself, but I thought of another problem. If the while loop
> is broken we need to exit, right. So set map.generator to 1 and give a
> good translated LOG_NORMAL message.
Instead of making a new translated string "Falling back to generator
1", I replaced the existing "Falling back to generator 2" with
"Falling back to generator %d", so the freelog can put in whatever
integer it likes without creating excessive translatable strings. I
don't understand the translation stuff, but I suppose the .po files
will need to be updated appropriately.
I tried something different for GnuPG, it may work better with other
mail clients now.
--
+-----------------------------------------------------------------
| PGP http://www.eng.uwaterloo.ca/student/cjmorlan/public-key.pgp
| Cameron Morland ---- Cameron@xxxxxxxxxx
|
| Long hair minimizes the need for barbers; socks can be done
| without; one leather jacket solves the coat problem for many
| years; suspenders are superfluous.
| --Einstein
+-----------------------------------------------------------------
? core.11259
? core.11261
? core.12061
? core.12065
? core.12156
? core.12417
? core.12421
? map.serv
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.142
diff -u -3 -p -r1.142 map.c
--- common/map.c 2003/09/11 11:30:42 1.142
+++ common/map.c 2003/09/18 17:21:18
@@ -1285,6 +1285,14 @@ void map_clear_special(int x, int y, enu
}
/***************************************************************
+ Remove any specials which may exist at these map co-ordinates.
+***************************************************************/
+void map_clear_all_specials(int x, int y)
+{
+ MAP_TILE(x, y)->special = S_NO_SPECIAL;
+}
+
+/***************************************************************
...
***************************************************************/
struct city *map_get_city(int x, int y)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.152
diff -u -3 -p -r1.152 map.h
--- common/map.h 2003/09/11 11:30:42 1.152
+++ common/map.h 2003/09/18 17:21:18
@@ -278,6 +278,7 @@ enum tile_special_type map_get_special(i
void map_set_terrain(int x, int y, enum tile_terrain_type ter);
void map_set_special(int x, int y, enum tile_special_type spe);
void map_clear_special(int x, int y, enum tile_special_type spe);
+void map_clear_all_specials(int x, int y);
bool is_real_map_pos(int x, int y);
bool is_normal_map_pos(int x, int y);
Index: server/mapgen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/mapgen.c,v
retrieving revision 1.116
diff -u -3 -p -r1.116 mapgen.c
--- server/mapgen.c 2003/09/11 12:09:46 1.116
+++ server/mapgen.c 2003/09/18 17:21:19
@@ -1632,16 +1632,22 @@ static bool create_island(int islemass,
/**************************************************************************
make an island, fill every tile type except plains
note: you have to create big islands first.
-**************************************************************************/
-static void make_island(int islemass, int starters,
- struct gen234_state *pstate)
+ Return TRUE if successful.
+ min_specific_island_size is a percent value.
+***************************************************************************/
+static bool make_island(int islemass, int starters,
+ struct gen234_state *pstate,
+ int min_specific_island_size)
{
- static long int tilefactor, balance, lastplaced;/* int may be only 2 byte !
*/
+ /* int may be only 2 byte ! */
+ static long int tilefactor, balance, lastplaced;
static long int riverbuck, mountbuck, desertbuck, forestbuck, swampbuck;
int i;
if (islemass == 0) {
+ /* this only runs to initialise static things, not to actually
+ * create an island. */
balance = 0;
pstate->isleindex = 3; /* 0= none, 1= arctic, 2= antarctic */
@@ -1663,31 +1669,44 @@ static void make_island(int islemass, in
lastplaced = pstate->totalmass;
} else {
- /* makes the islands here */
+ /* makes the islands this big */
islemass = islemass - balance;
/* don't create continents without a number */
- if (pstate->isleindex >= MAP_NCONT)
- return;
+ if (pstate->isleindex >= MAP_NCONT) {
+ return FALSE;
+ }
- if(islemass>lastplaced+1+lastplaced/50)/*don't create big isles we can't
place*/
- islemass= lastplaced+1+lastplaced/50;
+ if (islemass > lastplaced + 1 + lastplaced / 50) {
+ /* don't create big isles we can't place */
+ islemass = lastplaced + 1 + lastplaced / 50;
+ }
/* isle creation does not perform well for nonsquare islands */
- if(islemass>(map.ysize-6)*(map.ysize-6))
- islemass= (map.ysize-6)*(map.ysize-6);
+ if (islemass > (map.ysize - 6) * (map.ysize - 6)) {
+ islemass = (map.ysize - 6) * (map.ysize - 6);
+ }
- if(islemass>(map.xsize-2)*(map.xsize-2))
- islemass= (map.xsize-2)*(map.xsize-2);
+ if (islemass > (map.xsize - 2) * (map.xsize - 2)) {
+ islemass = (map.xsize - 2) * (map.xsize - 2);
+ }
i = islemass;
- if (i <= 0) return;
+ if (i <= 0) {
+ return FALSE;
+ }
islands[pstate->isleindex].starters = starters;
freelog(LOG_VERBOSE, "island %i", pstate->isleindex);
- while (!create_island(i--, pstate) && i * 10 > islemass) {
- /* nothing */
+ /* keep trying to place an island, and decrease the size of
+ * the island we're trying to create until we succeed.
+ * If we get too small, return an error. */
+ while (!create_island(i, pstate)) {
+ if (i < islemass * min_specific_island_size / 100) {
+ return FALSE;
+ }
+ i--;
}
i++;
lastplaced= i;
@@ -1736,6 +1755,7 @@ static void make_island(int islemass, in
pstate->isleindex++;
map.num_continents++;
}
+ return TRUE;
}
/**************************************************************************
@@ -1752,6 +1772,7 @@ static void initworld(struct gen234_stat
for (x = 0 ; x < map.xsize ; x++) {
map_set_terrain(x, y, T_OCEAN);
map_set_continent(x, y, 0);
+ map_clear_all_specials(x, y);
map_set_owner(x, y, NULL);
}
for (x = 0 ; x < map.xsize; x++) {
@@ -1769,12 +1790,19 @@ static void initworld(struct gen234_stat
}
}
map.num_continents = 2;
- make_island(0, 0, pstate);
+ make_island(0, 0, pstate, 0);
islands[2].starters = 0;
islands[1].starters = 0;
islands[0].starters = 0;
}
+/* This variable is the Default Minimum Specific Island Size,
+ * ie the smallest size we'll typically permit our island, as a % of
+ * the size we wanted. So if we ask for an island of size x, the island
+ * creation will return if it would create an island smaller than
+ * x * DMSIS / 100 */
+#define DMSIS 10
+
/**************************************************************************
island base map generators
**************************************************************************/
@@ -1784,33 +1812,67 @@ static void mapgenerator2(void)
struct gen234_state state;
struct gen234_state *pstate = &state;
int i;
+ bool done = 0;
int spares= 1;
/* constant that makes up that an island actually needs additional space */
+ /* put 70% of land in big continents,
+ * 20% in medium, and
+ * 10% in small. */
+ int bigfrac = 70, midfrac = 20, smallfrac = 10;
+
if (map.landpercent > 85) {
map.generator = 1;
return;
}
-
- pstate->totalmass =
- ((map.ysize - 6 - spares) * map.landpercent * (map.xsize - spares)) /
- 100;
- /*!PS: The weights NEED to sum up to totalweight (dammit) */
- /* copying the flow of the make_island loops is the safest way */
+ pstate->totalmass = ((map.ysize - 6 - spares) * map.landpercent
+ * (map.xsize - spares)) / 100;
totalweight = 100 * game.nplayers;
- initworld(pstate);
+ while (!done && bigfrac > midfrac) {
+ done = TRUE;
+ initworld(pstate);
+
+ /* Create one big island for each player. */
+ for (i = game.nplayers; i > 0; i--) {
+ if (!make_island(bigfrac * pstate->totalmass / totalweight,
+ 1, pstate, 95)) {
+ /* we couldn't make an island at least 95% as big as we wanted,
+ * and since we're trying hard to be fair, we need to start again,
+ * with all big islands reduced slightly in size.
+ * Take the size reduction from the big islands and add it to the
+ * small islands to keep overall landmass unchanged.
+ * Note that the big islands can get very small if necessary, and
+ * the smaller islands will not exist if we can't place them
+ * easily. */
+ freelog(LOG_VERBOSE,
+ "Island too small, trying again with all smaller islands.\n");
+ midfrac += bigfrac * 0.01;
+ smallfrac += bigfrac * 0.04;
+ bigfrac *= 0.95;
+ done = FALSE;
+ break;
+ }
+ }
+ }
- for (i = game.nplayers; i > 0; i--) {
- make_island(70 * pstate->totalmass / totalweight, 1, pstate);
+ if (bigfrac <= midfrac) {
+ /* We could never make adequately big islands. */
+ freelog(LOG_NORMAL, _("Falling back to generator %d."), 1);
+ map.generator = 1;
+ return;
}
+
+ /* Now place smaller islands, but don't worry if they're small,
+ * or even non-existent. One medium and one small per player. */
for (i = game.nplayers; i > 0; i--) {
- make_island(20 * pstate->totalmass / totalweight, 0, pstate);
+ make_island(midfrac * pstate->totalmass / totalweight, 0, pstate, DMSIS);
}
for (i = game.nplayers; i > 0; i--) {
- make_island(10 * pstate->totalmass / totalweight, 0, pstate);
+ make_island(smallfrac * pstate->totalmass / totalweight, 0, pstate, DMSIS);
}
+
make_plains();
free(height_map);
height_map = NULL;
@@ -1858,8 +1920,11 @@ static void mapgenerator3(void)
if(islandmass<3*maxmassdiv6 && game.nplayers*2<landmass )
islandmass= (landmass)/(bigislands);
- if( map.xsize < 40 || map.ysize < 40 || map.landpercent>80 )
- { freelog(LOG_NORMAL,_("Falling back to generator 2.")); mapgenerator2();
return; }
+ if (map.xsize < 40 || map.ysize < 40 || map.landpercent > 80) {
+ freelog(LOG_NORMAL, _("Falling back to generator %d."), 2);
+ map.generator = 2;
+ return;
+ }
if(islandmass<2)
islandmass= 2;
@@ -1870,7 +1935,7 @@ static void mapgenerator3(void)
while (pstate->isleindex - 2 <= bigislands && checkmass > islandmass
&& ++j < 500) {
- make_island(islandmass, 1, pstate);
+ make_island(islandmass, 1, pstate, DMSIS);
}
if(j==500){
@@ -1892,7 +1957,7 @@ static void mapgenerator3(void)
if(size<2) size=2;
make_island(size, (pstate->isleindex - 2 <= game.nplayers) ? 1 : 0,
- pstate);
+ pstate, DMSIS);
}
make_plains();
@@ -1947,18 +2012,20 @@ static void mapgenerator4(void)
i = game.nplayers / 2;
if ((game.nplayers % 2) == 1) {
- make_island(bigweight * 3 * pstate->totalmass / totalweight, 3, pstate);
+ make_island(bigweight * 3 * pstate->totalmass / totalweight, 3,
+ pstate, DMSIS);
} else {
i++;
}
while ((--i) > 0) {
make_island(bigweight * 2 * pstate->totalmass / totalweight, 2,
- pstate);}
+ pstate, DMSIS);
+ }
for (i = game.nplayers; i > 0; i--) {
- make_island(20 * pstate->totalmass / totalweight, 0, pstate);
+ make_island(20 * pstate->totalmass / totalweight, 0, pstate, DMSIS);
}
for (i = game.nplayers; i > 0; i--) {
- make_island(10 * pstate->totalmass / totalweight, 0, pstate);
+ make_island(10 * pstate->totalmass / totalweight, 0, pstate, DMSIS);
}
make_plains();
free(height_map);
@@ -1968,6 +2035,8 @@ static void mapgenerator4(void)
freelog(LOG_VERBOSE, "%ld mass left unplaced", checkmass);
}
}
+
+#undef DMSIS
/**************************************************************************
Recursive function which does the work for generator 5
pgpmxycDbyY8w.pgp
Description: PGP signature
- [Freeciv-Dev] Re: Make gen2 fair (PR#4659),
Cameron Morland <=
|
|