Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2004:
[Freeciv-Dev] Re: (PR#8632) Easy way to set map size with auto ratios (s
Home

[Freeciv-Dev] Re: (PR#8632) Easy way to set map size with auto ratios (s

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#8632) Easy way to set map size with auto ratios (seteables if desired)
From: "Marcelo Burda" <mburda@xxxxxxxxx>
Date: Mon, 31 May 2004 06:49:08 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=8632 >

Le lun 31/05/2004 à 14:53, rwetmore@xxxxxxxxxxxx a écrit :
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=8632 >
> 
> 
> The ratio form is still an unnecessarily complex and unneeded way to handle 
> things and should be dropped from the patch. It should never be exposed to
> the advanced end user that accesses the lowest level parameters, let along 
> the naive end user that should work through a simple interface layer that 
> consolidates coordinated options into common scenarios.
LAST CHANGED:
-after 2 person asked me to drop the ratio option for user i can't make
any else tha drop this option.

-limit size to 29k tiles instead 30, because this is the limit for the
5:8 ratio in iso maps used for classic and uranus topos

-drop all referentias to ratio in help of the size
-- 
 . /  .     '    ,    .      (*)   '        `     '      `    .    
  |    ,  |   `     ,     .      ,   '  Marcelo Julián Burda      .
 /  '     \     `     \@_     '      .        '      `        '    
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff -ruN -Xfreeciv/diff_ignore freeciv/client/packhand.c 
freeciv_/client/packhand.c
--- freeciv/client/packhand.c   2004-05-31 16:24:30.000000000 +0200
+++ freeciv_/client/packhand.c  2004-05-31 17:36:50.000000000 +0200
@@ -1307,9 +1307,12 @@
 ****************************************************************************/
 void handle_map_info(int xsize, int ysize, int topology_id)
 {
-  map.xsize = xsize;
-  map.ysize = ysize;
+  map.size = 0; /*dummy value: use server sended sizes */
+  map.ratio = 100;/*dummy value: use server sended sizes */
   map.topology_id = topology_id;
+  map.xsize = xsize; /* befor map_init_topology, it can need sizes */
+  map.ysize = ysize;
+  map_init_topology(FALSE); /* if arg is FALSE, sizes are kip unchanged */
 
   map_allocate();
   init_client_goto();
diff -ruN -Xfreeciv/diff_ignore freeciv/common/capstr.c freeciv_/common/capstr.c
--- freeciv/common/capstr.c     2004-05-22 09:17:20.000000000 +0200
+++ freeciv_/common/capstr.c    2004-05-31 17:36:50.000000000 +0200
@@ -75,7 +75,7 @@
  */
 
 #define CAPABILITY "+1.14.delta +last_turns_shield_surplus veteran +orders " \
-                   "+starter +union +iso_maps +orders2client " \
+                   "+starter +union +iso_maps +big_map_size +orders2client " \
                    "+change_production +tilespec1 +no_earth +trans " \
                    "+want_hack invasions bombard +killstack2 spec"
 
@@ -95,6 +95,8 @@
  *
  * "iso_maps" means iso-maps are supported by both server and client!
  *
+ * "big_map_size" means size info sended UINT16 by both server and client! 
+ *
  * "orders2client" means that the server sends back the orders to the client.
  *
  * "change_production" is the E_CITY_PRODUCTION_CHANGED event.
diff -ruN -Xfreeciv/diff_ignore freeciv/common/map.c freeciv_/common/map.c
--- freeciv/common/map.c        2004-05-27 12:55:38.000000000 +0200
+++ freeciv_/common/map.c       2004-05-31 17:41:07.000000000 +0200
@@ -176,9 +176,18 @@
 ***************************************************************/
 void map_init(void)
 {
-  map.topology_id = MAP_DEFAULT_TOPO;
-  map.xsize                 = MAP_DEFAULT_WIDTH;
-  map.ysize                 = MAP_DEFAULT_HEIGHT;
+  map.topology_id           = MAP_DEFAULT_TOPO;
+  map.size                  = MAP_DEFAULT_SIZE;
+  map.ratio                 = MAP_DEFAULT_RATIO;
+  /*
+    begin comment
+    To be set by map_init_topology(), begin with 0 teorical is ok but
+    I set it to some not zero value to fix a bug where
+    client execute advance_unit_focus befor server send sizes of the map!
+  */
+  map.xsize                 = MAP_MIN_LINEAR_SIZE;  
+  map.ysize                 = MAP_MIN_LINEAR_SIZE;
+  /*end comment                                               [mburda]*/
   map.seed                  = MAP_DEFAULT_SEED;
   map.riches                = MAP_DEFAULT_RICHES;
   map.huts                  = MAP_DEFAULT_HUTS;
@@ -200,6 +209,111 @@
   map.have_huts             = FALSE;
 }
 
+/* ***************************************************************
+   return the maximum common denominator or greatest common factor
+   *************************************************************** */
+static int gcf(int a, int b) {
+  int min = MIN(a, b), max = MAX(a, b);
+
+  if (min == 0) return max;
+  return gcf(min, max - min);
+}
+
+/*
+ * This is the core of calculate size of the maps 
+ * final value are calculate to get defined ratios size in natural
+ * coordinated
+ * xsize and ysize are even numbers
+ * if iso-map ysize%4 == 0 to avoid any type of problems in
+ * extended topologies and iso-maps
+ */   
+static void set_ratio(double base_size, int Xratio, int Yratio)
+{
+  int i_size, iso, newratio, GCF = gcf(Xratio, Yratio);
+  /*
+   * Simplify the common divisor in ratios 
+   * ratios as 9:9 8:8 7:7 are converted to 1:1
+   */
+  Xratio /= GCF;
+  Yratio /= GCF;
+  /*
+   Correct exesives ratios
+  */
+  if( Xratio / Yratio >= 3) {
+    Xratio = 3;
+    Yratio = 1;
+  }
+  if( Yratio / Xratio >= 3) {
+    Xratio = 1;
+    Yratio = 3 ;
+  }
+  newratio = 10 * Xratio + Yratio;
+  /* set corrected ratio in map.ratio if these values are set by user */
+  if( map.ratio != 100 && newratio != map.ratio) {
+    map.ratio = newratio;
+    freelog(LOG_NORMAL,
+       _("The user defined ratios was corrected to %d  \n"), map.ratio);
+  }
+  /* in TF_ISO we need double map.ysize/map.ysize factor */ 
+  iso = topo_has_flag(TF_ISO)? 2 : 1;
+  /* Get a integer for the internal i_size var,
+     this alow to make easly even numbers */
+  i_size = floor(0.49 + sqrt(250.0 * base_size / (Xratio * Yratio * iso)));
+  /* verify for map.xsize and map.ysize minimum value*/ 
+  while (MIN(Xratio, iso * Yratio)* 2 * i_size < MAP_MIN_LINEAR_SIZE)
+  { i_size++; };
+  /* set map.[xy]size as even numbers (and ysize %4 == 0 for TF_ISO)*/
+  map.xsize =       2 * Xratio * i_size;
+  map.ysize = iso * 2 * Yratio * i_size;
+  /* Verify up limit for map coordinates and correct it if needed */
+  if (MAX(MAP_WIDTH,MAP_HEIGHT) - 1 > MAP_MAX_LINEAR_SIZE ) {
+      /* make a more litle map if possible */
+    assert(base_size > 0.1);
+    set_ratio(base_size - 0.1, Xratio, Yratio);
+    return;
+  }
+  if( map.size > base_size + 0.9 ) { /* Warning when size is set useless big 
*/ 
+      freelog(LOG_NORMAL,
+        _("Asked size of %d is too big for this topology"), map.size);
+  }
+  freelog(LOG_NORMAL,
+        _("Creating a map of size of %2.1fk tiles"),
+         base_size);
+  freelog(LOG_DEBUG,
+        "map.xsize and map.ysize are seted to %d and %d ",
+         map.xsize, map.ysize);
+}
+
+/*************************************************************************** 
+ map_init_topology(set_sizes) need to be called after changes on
+ map.topology_id, map.size and map.ratio was donned.
+ this calculate map.xsize and map.ysize
+
+ in client or when loading savegames set_sizes arg can be passed FALSE to
+ alow code to set direcly xsize and ysize 
+                                                                [mburda]
+*************************************************************************/
+void map_init_topology(bool set_sizes)
+{
+  /* Comment: This is harded related to enum topo_flag */
+  const int default_ratios[4] =
+      { AUTO_RATIO_FLAT, AUTO_RATIO_CLASSIC,
+       AUTO_RATIO_URANUS, AUTO_RATIO_TORUS};
+  const int id = 0x3 & map.topology_id;
+  
+  assert( TF_WRAPX == 0x1 && TF_WRAPY == 0x2 );
+  /* End Comment */
+
+  /* Set map.xsize and map.ysize */
+  if(set_sizes) {
+    if (map.ratio == 100) {
+      set_ratio(map.size, default_ratios[id] / 10, default_ratios[id] % 10);
+    } else {
+      set_ratio(map.size, map.ratio / 10, map.ratio % 10);
+    }
+  }
+}
+
 /***************************************************************
 ...
 ***************************************************************/
diff -ruN -Xfreeciv/diff_ignore freeciv/common/map.h freeciv_/common/map.h
--- freeciv/common/map.h        2004-05-27 12:55:38.000000000 +0200
+++ freeciv_/common/map.h       2004-05-31 17:38:08.000000000 +0200
@@ -117,6 +117,7 @@
 
 struct civ_map { 
   int topology_id;
+  int size, ratio; /* used to calculate [xy]size */
   int xsize, ysize; /* native dimensions */
   int seed;
   int riches;
@@ -147,8 +148,8 @@
 
 enum topo_flag {
   /* Bit-values. */
-  TF_WRAPX = 1,
-  TF_WRAPY = 2,
+  TF_WRAPX = 1, /* correct map_init_topology if changed */
+  TF_WRAPY = 2, /* correct map_init_topology if changed */
   TF_ISO = 4
 };
 
@@ -156,6 +157,8 @@
 
 #define topo_has_flag(flag) ((CURRENT_TOPOLOGY & (flag)) != 0)
 
+void map_init_topology(bool set_sizes);
+
 bool map_is_empty(void);
 void map_init(void);
 void map_allocate(void);
@@ -260,6 +263,15 @@
 #define NATURAL_WIDTH (topo_has_flag(TF_ISO) ? 2 * map.xsize : map.xsize)
 #define NATURAL_HEIGHT map.ysize
 
+#define MAP_WIDTH \
+   (topo_has_flag(TF_ISO) \
+    ? (map.xsize + map.ysize / 2) \
+    : map.xsize)
+#define MAP_HEIGHT \
+(topo_has_flag(TF_ISO) \
+    ? (map.xsize + map.ysize / 2) \
+    : map.ysize)
+  
 static inline int map_pos_to_index(int map_x, int map_y);
 
 /* index_to_map_pos(int *, int *, int) inverts map_pos_to_index */
@@ -636,13 +648,43 @@
 #define MAP_MIN_HUTS             0
 #define MAP_MAX_HUTS             500
 
-#define MAP_DEFAULT_WIDTH        80
-#define MAP_MIN_WIDTH            40
-#define MAP_MAX_WIDTH            200
-
-#define MAP_DEFAULT_HEIGHT       50
-#define MAP_MIN_HEIGHT           25
-#define MAP_MAX_HEIGHT           100
+/* size of the map in thusand of tiles */
+#define MAP_DEFAULT_SIZE         4
+#define MAP_MIN_SIZE             1
+#define MAP_MAX_SIZE             29
+
+/*
+ * This define the max linear size in map coordinates
+ * this must be liter than 255, this value is reserved for net usage
+ * COORD types is defined as UINT8 (used to send map coordinates only)
+ * XYSIZE was defined as UINT16 then, in native coordinates these
+ *        values can be larger.
+ */
+#define MAP_MAX_LINEAR_SIZE      254
+#define MAP_MIN_LINEAR_SIZE      8
+#define MAP_MAX_WIDTH    MAP_MAX_LINEAR_SIZE
+#define MAP_MAX_HEIGHT    MAP_MAX_LINEAR_SIZE
+/*
+ * This value determine the x:y ration of the map in NATURAL coordinated
+ * This ratio need to be corrected for NATIVE coordinated in
+ * iso-map by a factor sqrt(2) as (x / sqrt(2)) : (y * sqrt (2))
+ * the spetial values 100 is the AUTO RATIO (this is the prefered value)
+ */
+#define MAP_DEFAULT_RATIO         100
+#define MAP_MIN_RATIO             11
+#define MAP_MAX_RATIO             100
+
+/*
+ * The auto ratios for knowns topologies
+ * Best for litles map sizes if (but not needed)
+ * get RATIO factor = Xratio*Yratio as litle as posible  
+ * 
+ * get DEFAULT RATIO <= 2:1 or 1:2                              
+ */
+#define AUTO_RATIO_FLAT           11
+#define AUTO_RATIO_CLASSIC        85 
+#define AUTO_RATIO_URANUS         58 
+#define AUTO_RATIO_TORUS          11
 
 #define MAP_ORIGINAL_TOPO        TF_WRAPX
 #define MAP_DEFAULT_TOPO         TF_WRAPX
diff -ruN -Xfreeciv/diff_ignore freeciv/common/packets.def 
freeciv_/common/packets.def
--- freeciv/common/packets.def  2004-05-28 11:34:56.000000000 +0200
+++ freeciv_/common/packets.def 2004-05-31 17:36:50.000000000 +0200
@@ -189,6 +189,7 @@
 
 # other typedefs
 type COORD             = UINT8
+type XYSIZE            = UINT16
 type YEAR              = SINT16
 type HP                = UINT8
 type PERCENT           = UINT8
@@ -345,8 +346,8 @@
 end
 
 PACKET_MAP_INFO=16; is-info,sc,lsend
-  COORD xsize;
-  COORD ysize;
+  XYSIZE xsize;
+  XYSIZE ysize;
   UINT8 topology_id;
 end
 
diff -ruN -Xfreeciv/diff_ignore freeciv/common/packets_gen.c 
freeciv_/common/packets_gen.c
--- freeciv/common/packets_gen.c        2004-05-28 11:35:13.000000000 +0200
+++ freeciv_/common/packets_gen.c       2004-05-31 17:41:11.000000000 +0200
@@ -3738,10 +3738,10 @@
   }
 
   if (BV_ISSET(fields, 0)) {
-    dio_get_uint8(&din, (int *) &real_packet->xsize);
+    dio_get_uint16(&din, (int *) &real_packet->xsize);
   }
   if (BV_ISSET(fields, 1)) {
-    dio_get_uint8(&din, (int *) &real_packet->ysize);
+    dio_get_uint16(&din, (int *) &real_packet->ysize);
   }
   if (BV_ISSET(fields, 2)) {
     dio_get_uint8(&din, (int *) &real_packet->topology_id);
@@ -3799,10 +3799,10 @@
   DIO_BV_PUT(&dout, fields);
 
   if (BV_ISSET(fields, 0)) {
-    dio_put_uint8(&dout, real_packet->xsize);
+    dio_put_uint16(&dout, real_packet->xsize);
   }
   if (BV_ISSET(fields, 1)) {
-    dio_put_uint8(&dout, real_packet->ysize);
+    dio_put_uint16(&dout, real_packet->ysize);
   }
   if (BV_ISSET(fields, 2)) {
     dio_put_uint8(&dout, real_packet->topology_id);
diff -ruN -Xfreeciv/diff_ignore freeciv/server/airgoto.c 
freeciv_/server/airgoto.c
--- freeciv/server/airgoto.c    2004-01-11 18:45:05.000000000 +0100
+++ freeciv_/server/airgoto.c   2004-05-31 17:36:50.000000000 +0200
@@ -172,12 +172,12 @@
     if (is_allied_city_tile(ptile, pplayer)
        && !is_non_allied_unit_tile(ptile, pplayer) ) {
       add_refuel_point(x, y, FUEL_CITY, 
-                       MAP_MAX_HEIGHT + MAP_MAX_WIDTH, 0, FALSE);
+                       MAP_HEIGHT + MAP_WIDTH, 0, FALSE);
     } else if (tile_has_special(ptile, S_AIRBASE)
                && !is_non_allied_unit_tile(ptile, pplayer)
                && !cities_only) {
       add_refuel_point(x, y, FUEL_AIRBASE, 
-                       MAP_MAX_HEIGHT + MAP_MAX_WIDTH, 0, FALSE);
+                       MAP_HEIGHT + MAP_WIDTH, 0, FALSE);
     }
   } whole_map_iterate_end;
 }
@@ -213,7 +213,7 @@
                                    int moves_per_turn, int max_fuel)
 {
   struct refuel *tmp;   
-  struct pqueue *rp_queue = pq_create(MAP_MAX_WIDTH);
+  struct pqueue *rp_queue = pq_create(MAP_WIDTH);
   short index;
 
   /* List of all refuel points of the player!  
@@ -225,7 +225,7 @@
 
   if (!same_pos(x, y, dest_x, dest_y)) {
     add_refuel_point(dest_x, dest_y, FUEL_GOAL, 
-                     MAP_MAX_HEIGHT + MAP_MAX_WIDTH, 0, FALSE);
+                     MAP_HEIGHT + MAP_WIDTH, 0, FALSE);
   }
 
   /* Process the starting point, no need to queue it
diff -ruN -Xfreeciv/diff_ignore freeciv/server/citytools.c 
freeciv_/server/citytools.c
--- freeciv/server/citytools.c  2004-05-28 11:35:27.000000000 +0200
+++ freeciv_/server/citytools.c 2004-05-31 17:36:50.000000000 +0200
@@ -280,7 +280,7 @@
   Nation_Type_id nation_list[game.nation_count], n;
   int queue_size;
 
-  static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; 
+  const int num_tiles = NATIVE_WIDTH * NATIVE_HEIGHT; 
 
   /* tempname must be static because it's returned below. */
   static char tempname[MAX_LEN_NAME];
@@ -371,7 +371,7 @@
     }
   }
 
-  for (i = 1; i <= num_tiles; i++ ) {
+  for (i = 1; i <= num_tiles; i++ ) { /* why num_tiles ?? [mburda] */
     my_snprintf(tempname, MAX_LEN_NAME, _("City no. %d"), i);
     if (!game_find_city_by_name(tempname)) {
       return tempname;
diff -ruN -Xfreeciv/diff_ignore freeciv/server/mapgen.c freeciv_/server/mapgen.c
--- freeciv/server/mapgen.c     2004-05-21 10:54:02.000000000 +0200
+++ freeciv_/server/mapgen.c    2004-05-31 17:36:50.000000000 +0200
@@ -1288,7 +1288,7 @@
 {
   /* save the current random state: */
   RANDOM_STATE rstate = get_myrand_state();
- 
+  
   if (map.seed==0)
     map.seed = (myrand(MAX_UINT32) ^ time(NULL)) & (MAX_UINT32 >> 1);
 
@@ -1303,7 +1303,8 @@
 
   /* don't generate tiles with mapgen==0 as we've loaded them from file */
   /* also, don't delete (the handcrafted!) tiny islands in a scenario */
-  if (map.generator != 0) {
+  if (map.generator != 0) { 
+    map_init_topology(TRUE);/* initialize map.xsize and map.ysize, etc */
     map_allocate();
     adjust_terrain_param();
     /* if one mapgenerator fails, it will choose another mapgenerator */
diff -ruN -Xfreeciv/diff_ignore freeciv/server/savegame.c 
freeciv_/server/savegame.c
--- freeciv/server/savegame.c   2004-05-31 16:24:32.000000000 +0200
+++ freeciv_/server/savegame.c  2004-05-31 17:36:50.000000000 +0200
@@ -345,14 +345,18 @@
 ***************************************************************/
 static void map_tiles_load(struct section_file *file)
 {
+  map.size = 0; /* dumy value: use [xy]size from load */
+  map.ratio= 100; /* dumy value: use [xy]size from load */
   map.topology_id = secfile_lookup_int_default(file, MAP_ORIGINAL_TOPO,
                                               "map.topology_id");
-
   /* In some cases we read these before, but not always, and
    * its safe to read them again:
+   * We set it befor call map_init_topology, eventually
+   *  map_init_topology will need its 
    */
   map.xsize=secfile_lookup_int(file, "map.width");
   map.ysize=secfile_lookup_int(file, "map.height");
+  map_init_topology(FALSE); /* this call not change [xy]size if arg is FALSE */
 
   map_allocate();
 
diff -ruN -Xfreeciv/diff_ignore freeciv/server/stdinhand.c 
freeciv_/server/stdinhand.c
--- freeciv/server/stdinhand.c  2004-05-27 12:55:39.000000000 +0200
+++ freeciv_/server/stdinhand.c 2004-05-31 17:37:44.000000000 +0200
@@ -254,13 +254,14 @@
   /* These should be grouped by sclass */
   
 /* Map size parameters: adjustable if we don't yet have a map */  
-  GEN_INT("xsize", map.xsize, SSET_MAP_SIZE, SSET_GEOLOGY, SSET_TO_CLIENT,
-         N_("Map width in squares"), "", NULL,
-         MAP_MIN_WIDTH, MAP_MAX_WIDTH, MAP_DEFAULT_WIDTH)
-    
-  GEN_INT("ysize", map.ysize, SSET_MAP_SIZE, SSET_GEOLOGY, SSET_TO_CLIENT,
-         N_("Map height in squares"), "", NULL,
-         MAP_MIN_HEIGHT, MAP_MAX_HEIGHT, MAP_DEFAULT_HEIGHT)
+  GEN_INT("size", map.size, SSET_MAP_SIZE, SSET_GEOLOGY, SSET_TO_CLIENT,
+          N_("Map size in 1,000 tiles units"),
+          N_("This value is used to determine xsize and ysize\n"
+             " size = 4 is a litle map of  4,000 tiles (default)\n"
+             " size = 20 is a Huge map of 20,000 tiles \n"
+            "The size can be limited by topology\n"
+            ", the real size will be auto reised to these maximals"), NULL,
+          MAP_MIN_SIZE,MAP_MAX_SIZE , MAP_DEFAULT_SIZE)
 
   GEN_INT("topology", map.topology_id, SSET_MAP_SIZE, SSET_GEOLOGY, 
           SSET_TO_CLIENT,
@@ -268,14 +269,14 @@
          N_("Two-dimensional maps can wrap at the north-south or \n"
             "east-west edges, and use a cartesian or isometric \n"
             "rectangular grid.  See the manual for further explanation.\n"
-             "  0 Flat Earth (unwrapped)\n"
-             "  1 Earth (wraps E-W)\n"
-             "  2 Uranus (wraps N-S)\n"
+             "  0 Flat Earth (unwrapped)      \n"
+             "  1 Earth (wraps E-W)           \n"
+             "  2 Uranus (wraps N-S)          \n"
              "  3 Donut World (wraps N-S, E-W)\n"
-            "  4 Flat Earth (isometric)\n"
-            "  5 Earth (isometric)\n"
-            "  6 Uranus (isometric)\n"
-            "  7 Donut World (isometric)"
+            "  4 Flat Earth (isometric)      \n"
+            "  5 Earth (isometric)           \n"
+            "  6 Uranus (isometric)          \n"
+            "  7 Donut World (isometric)     "
           ), NULL, 
          MAP_MIN_TOPO, MAP_MAX_TOPO, MAP_DEFAULT_TOPO)
 

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