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

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

[Top] [All Lists]

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

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

Ok i add a test to limit maximum ratios to 3:1
the code are more simple and clear, i limit the unnesesary tests.
the core is now:
+  /* in TF_ISO we need double map.ysize/map.ysize factor */ 
+  int iso = topo_has_flag(TF_ISO)? 2 : 1;
+  /* get a integer for the internal i_size var,this alow to make easly
even numbers */
+  int i_size = floor(0.49 + sqrt(250.0 * base_size / (Xratio * Yratio *
iso)));
+  /* verify for map.xsize and map.ysize estimated minimum value*/
+  /* this is make there to avoid a too complex code, but it is not exact */
+  int i_size_min = MIN(1, MAP_MIN_LINEAR_SIZE / MIN(Xratio, Yratio *
iso) / 2);
+  if (i_size < i_size_min) { i_size = i_size_min; };
+  
+  /* 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) >= MAP_MAX_LINEAR_SIZE) {     
                          /* make a more litle map if possible */
+    assert(base_size > 0.1);
+    setmapratio2(base_size - 0.1, Xratio, Yratio);
+    return;
+  }
I go sleep. 
bye
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/client/packhand.c 
freeciv-cvs-Apr-29_/client/packhand.c
--- freeciv-cvs-Apr-29/client/packhand.c        2004-04-28 07:11:35.000000000 
+0200
+++ freeciv-cvs-Apr-29_/client/packhand.c       2004-05-06 01:45:05.000000000 
+0200
@@ -1303,9 +1303,13 @@
 ****************************************************************************/
 void handle_map_info(int xsize, int ysize, int topology_id)
 {
+  map.size = 0; /* use server sended sizes */
+  map.ratio = 100;
+  map.topology_id = topology_id;
+  map_init_topology();
+
   map.xsize = xsize;
   map.ysize = ysize;
-  map.topology_id = topology_id;
 
   map_allocate();
   init_client_goto();
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/common/map.c 
freeciv-cvs-Apr-29_/common/map.c
--- freeciv-cvs-Apr-29/common/map.c     2004-04-21 07:11:39.000000000 +0200
+++ freeciv-cvs-Apr-29_/common/map.c    2004-05-06 02:39:34.000000000 +0200
@@ -176,9 +176,11 @@
 ***************************************************************/
 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;
+  map.xsize                 = 0; /* to be set by map_init_topology() or 
eventualy load */
+  map.ysize                 = 0;
   map.seed                  = MAP_DEFAULT_SEED;
   map.riches                = MAP_DEFAULT_RICHES;
   map.huts                  = MAP_DEFAULT_HUTS;
@@ -199,6 +201,116 @@
   map.have_specials         = FALSE;
   map.have_rivers_overlay   = FALSE;
   map.have_huts             = FALSE;
+  map_init_topology(); /* correct xsize/ysize values if needed */
+}
+
+/*
+ * 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 setmapratio2(double base_size, int Xratio, int Yratio)
+{
+  /* if map.xsize and map.ysize are set from server  do nothing*/
+    if (base_size == 0) 
+    return;
+
+  /*
+   Correct exesives ratios
+  */
+    if( Xratio / Yratio >= 3) {
+      Xratio = 3;
+      Yratio = 1 ;
+    }
+    if( Yratio / Xratio >= 3) {
+      Xratio = 1;
+      Yratio = 3 ;
+    }
+
+  /*
+   * Simplify the prime common divisor in ratios 
+   * ratios as 9:9 8:8 7:7 are converted to 1:1
+   */
+  if ((Xratio % 2) == 0 && (Yratio % 2) == 0) {
+    setmapratio2(base_size, Xratio / 2, Yratio / 2);
+    return;
+  }
+  if ((Xratio % 3) == 0 && (Yratio % 3) == 0) {
+    setmapratio2(base_size, Xratio / 3, Yratio / 3);
+    return;
+  }
+  if ((Xratio % 5) == 0 && (Yratio % 5) == 0) {
+    setmapratio2(base_size, Xratio / 5, Yratio / 5);
+    return;
+  }
+  if ((Xratio % 7) == 0 && (Yratio % 7) == 0) {
+    setmapratio2(base_size, Xratio / 7, Yratio / 7);
+    return;
+  }
+
+  /* in TF_ISO we need double map.ysize/map.ysize factor */ 
+  int iso = topo_has_flag(TF_ISO)? 2 : 1;
+  /* get a integer for the internal i_size var,this alow to make easly even 
numbers */
+  int i_size = floor(0.49 + sqrt(250.0 * base_size / (Xratio * Yratio * iso)));
+  /* verify for map.xsize and map.ysize estimated minimum value*/
+  /* this is make there to avoid a too complex code, but it is not exact */
+  int i_size_min = MIN(1, MAP_MIN_LINEAR_SIZE / MIN(Xratio, Yratio * iso) / 2);
+  if (i_size < i_size_min) { i_size = i_size_min; };
+  
+  /* 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) >= MAP_MAX_LINEAR_SIZE) {      /* make a more 
litle map if possible */
+    assert(base_size > 0.1);
+    setmapratio2(base_size - 0.1, Xratio, Yratio);
+    return;
+  }
+}
+
+/* auto-ratios can't change map.ratio */
+static void auto_ratio(int ratio)
+{
+  assert(ratio >= 11 && ratio < 100);
+  setmapratio2(map.size, ratio / 10,(ratio % 10));
+}
+
+static void user_ratio(void)
+{
+  assert(map.ratio >= 11 && map.ratio <= 100);
+  if (map.ratio != 100)
+      setmapratio2(map.size, map.ratio / 10,
+                  (map.ratio % 10));
+}
+
+#define INIT_TOPOLOGIE_CASE(TOPO,DEFAULTRATIO)                         \
+ case TOPO:                                                            \
+       if( map.ratio == 100){                                          \
+         auto_ratio(DEFAULTRATIO);                                     \
+       } else { user_ratio(); }                                        \
+       break;
+
+/*************************************************************************** 
+ map_init_topology() 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 map.size can be set to zero to
+ alow code to set direcly xsize and ysize 
+                                                                [mburda]
+*************************************************************************/
+void map_init_topology( void)
+{
+  switch (map.topology_id & (TF_WRAPX |TF_WRAPY)) {
+    INIT_TOPOLOGIE_CASE(0, AUTO_RATIO_FLAT);
+    INIT_TOPOLOGIE_CASE((TF_WRAPX |TF_WRAPY), AUTO_RATIO_TORUS);
+    INIT_TOPOLOGIE_CASE(TF_WRAPY, AUTO_RATIO_URANUS);
+    INIT_TOPOLOGIE_CASE(TF_WRAPX, AUTO_RATIO_CLASSIC);
+  };
 }
 
 /***************************************************************
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/common/map.h 
freeciv-cvs-Apr-29_/common/map.h
--- freeciv-cvs-Apr-29/common/map.h     2004-04-30 07:11:50.000000000 +0200
+++ freeciv-cvs-Apr-29_/common/map.h    2004-05-06 02:33:06.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;
@@ -154,6 +155,8 @@
 
 #define topo_has_flag(flag) ((CURRENT_TOPOLOGY & (flag)) != 0)
 
+void map_init_topology(void );
+
 bool map_is_empty(void);
 void map_init(void);
 void map_allocate(void);
@@ -219,6 +222,17 @@
 (    (dest_x) = DIR_DX[(dir)],         \
      (dest_y) = DIR_DY[(dir)])
 
+#define NAT_WIDTH map.xsize
+#define NAT_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)
 /*
  * Returns true if the step yields a new valid map position. If yes
  * (dest_x, dest_y) is set to the new map position.
@@ -589,13 +603,44 @@
 #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             2
+#define MAP_MAX_SIZE             20
+
+/*
+ * This define the max linear size in map or native coordinates
+ * this must be liter than 255, this value is reserved for net usage
+ */
+#define MAP_MAX_LINEAR_SIZE      254
+#define MAP_MIN_LINEAR_SIZE      8
+
+/*
+ * 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 if (but not needed)
+ * get RATIO factor = Xratio*Yratio as litle as posible
+ * this is best for litles map sizes                        
+ * get DEFAULT RATIO <= 2:1 or 1:2                              
+ */
+#define AUTO_RATIO_FLAT           11
+#define AUTO_RATIO_CLASSIC        85 
+#define AUTO_RATIO_URANUS         74 
+#define AUTO_RATIO_TORUS          11
+
+#define MAP_MIN_WIDTH            MAP_MIN_LINEAR_SIZE
+#define MAP_MAX_WIDTH            MAP_MAX_LINEAR_SIZE
+#define MAP_MIN_HEIGHT           MAP_MIN_LINEAR_SIZE
+#define MAP_MAX_HEIGHT           MAP_MAX_LINEAR_SIZE
 
 #define MAP_ORIGINAL_TOPO        TF_WRAPX
 #define MAP_DEFAULT_TOPO         TF_WRAPX
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/server/savegame.c 
freeciv-cvs-Apr-29_/server/savegame.c
--- freeciv-cvs-Apr-29/server/savegame.c        2004-04-05 21:04:24.000000000 
+0200
+++ freeciv-cvs-Apr-29_/server/savegame.c       2004-05-06 01:45:05.000000000 
+0200
@@ -323,8 +323,11 @@
 ***************************************************************/
 static void map_tiles_load(struct section_file *file)
 {
+  map.size = 0; /* use xize/ysize from load */
+  map.ratio= 100;
   map.topology_id = secfile_lookup_int_default(file, MAP_ORIGINAL_TOPO,
                                               "map.topology_id");
+  map_init_topology(); /* this call never change [xy]size */
 
   /* In some cases we read these before, but not always, and
    * its safe to read them again:
diff -ruN -Xdiff_ignore freeciv-cvs-Apr-29/server/stdinhand.c 
freeciv-cvs-Apr-29_/server/stdinhand.c
--- freeciv-cvs-Apr-29/server/stdinhand.c       2004-04-25 07:11:33.000000000 
+0200
+++ freeciv-cvs-Apr-29_/server/stdinhand.c      2004-05-06 02:41:13.000000000 
+0200
@@ -253,14 +253,24 @@
   /* 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"), NULL,
+          MAP_MIN_SIZE,MAP_MAX_SIZE , MAP_DEFAULT_SIZE)
+
+   GEN_INT("ratio", map.ratio, SSET_MAP_SIZE, SSET_GEOLOGY, SSET_TO_CLIENT,
+          N_("Map ratio, keep it default value of 100 (auto)\n"),
+          N_("This value is used to determine xsize and ysize \n"
+            " 100 is the default ratio determined by the topology_id\n"
+            "Otherwise first digit is the x factor \n"
+            "and second digit the y factor of the x:y ratio \n"
+             " 11 is 1:1 ratio, 85 is a 8:5 ratio. \n"
+            "Extreme ratio (more than 3:1 or 1:3) are not alowed \n"
+            "Change it at your own risk!"
+             ), NULL,
+          MAP_MIN_RATIO, MAP_MAX_RATIO , MAP_DEFAULT_RATIO)
   GEN_INT("topology", map.topology_id, SSET_MAP_SIZE, SSET_GEOLOGY, 
           SSET_TO_CLIENT,
          N_("The map topology index"),
@@ -3569,6 +3579,7 @@
   }
 
   if (!check && do_update) {
+    map_init_topology(); /* update map.[xy]size from last changes */
     /* 
      * send any modified game parameters to the clients -- if sent
      * before RUN_GAME_STATE, triggers a popdown_races_dialog() call

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