Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2001:
[Freeciv-Dev] [PATCH] base_real_map_distance (PR#1049)
Home

[Freeciv-Dev] [PATCH] base_real_map_distance (PR#1049)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] [PATCH] base_real_map_distance (PR#1049)
From: jdorje@xxxxxxxxxxxxxxxxxxxxx
Date: Thu, 1 Nov 2001 06:26:48 -0800 (PST)

This patch introduces a new topology function,
base_real_map_distance().  It performs a similar function to
real_map_distance, but also finds a distance vector from the source to
the destination coordinate pair.  It also replaces xdist and ydist.

A function like this is absolutely essential for iso-rectangular
topologies.  xdist() and ydist() will not work because you cannot find
the distance along one coordinate axis independently of the other.

jason
? rc
? old
? topology
? corecleanup_08.ReadMe
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.98
diff -u -r1.98 map.c
--- common/map.c        2001/10/30 10:59:19     1.98
+++ common/map.c        2001/11/01 14:09:30
@@ -288,28 +288,10 @@
 /***************************************************************
 ...
 ***************************************************************/
-int xdist(int x0, int x1)
-{
-  int dist = (x0 > x1) ? x0 - x1 : x1 - x0;
-  return MIN(dist, map.xsize-dist);
-}
-
-/***************************************************************
-...
-***************************************************************/
-int ydist(int y0, int y1)
-{
-  return (y0 > y1) ? y0 - y1 : y1 - y0;
-}
-
-/***************************************************************
-...
-***************************************************************/
 int real_map_distance(int x0, int y0, int x1, int y1)
 {
-  int xd = xdist(x0, x1);
-  int yd = ydist(y0, y1);
-  return MAX(xd, yd);
+  int xd, yd;
+  return base_real_map_distance(&xd, &yd, x0, y0, x1, y1);
 }
 
 /***************************************************************
@@ -317,8 +299,10 @@
 ***************************************************************/
 int sq_map_distance(int x0, int y0, int x1, int y1)
 {
-  int xd = xdist(x0, x1);
-  int yd = ydist(y0, y1);
+  /* We assume base_real_map_distance gives us the vector with
+     the minimum squared distance.  Right now this is true. */
+  int xd, yd;
+  base_real_map_distance(&xd, &yd, x0, y0, x1, y1);
   return (xd*xd + yd*yd);
 }
 
@@ -327,7 +311,11 @@
 ***************************************************************/
 int map_distance(int x0, int y0, int x1, int y1)
 {
-  return xdist(x0, x1) + ydist(y0, y1);
+  /* We assume base_real_map_distance gives us the vector with
+     the minimum map distance.  Right now this is true. */
+  int xd, yd;
+  base_real_map_distance(&xd, &yd, x0, y0, x1, y1);
+  return abs(xd) + abs(yd);
 }
 
 /***************************************************************
@@ -1340,6 +1328,32 @@
 }
 
 /**************************************************************************
+Topology function to find the minimum "real" distance between positions
+(x0, y0) and (x1, y1).  We find not only the distance but the vector
+(*dx, *dy) that has that "real" distance. If there is more than one vector
+with equal distance, no guarantee is made about which is found.
+
+Real distance is defined as the larger of the distances in the x and y
+direction; since units can travel diagonally this is the "real" distance
+a unit has to travel to get from point to point.
+
+(See also: real_map_distance, map_distance, and sq_map_distance.)
+**************************************************************************/
+int base_real_map_distance(int *dx, int *dy, int x0, int y0, int x1, int y1)
+{
+  if (x0 > x1)
+    *dx = x0 - x1;
+  else
+    *dx = x1 - x0;
+  if (*dx > map.xsize - *dx)
+    *dx = map.xsize - *dx;
+
+  *dy = y1 - y0;
+
+  return MAX(abs(*dx), abs(*dy));
+}
+
+/**************************************************************************
 Random neighbouring square.
 **************************************************************************/
 void rand_neighbour(int x0, int y0, int *x, int *y)
@@ -1436,11 +1450,13 @@
 **************************************************************************/
 int is_move_cardinal(int start_x, int start_y, int end_x, int end_y)
 {
+  int diff_x, diff_y;
   assert(is_real_tile(start_x, start_y) && is_real_tile(end_x, end_y));
   normalize_map_pos(&start_x, &start_y);
   normalize_map_pos(&end_x, &end_y);
   assert(is_tiles_adjacent(start_x, start_y, end_x, end_y));
 
-  /* FIXME: this check will not work with an orthogonal map */
-  return (start_x == end_x) || (start_y == end_y);
+  /* This check could be done better. */
+  base_real_map_distance(&diff_x, &diff_y, start_x, start_y, end_x, end_y);
+  return (diff_x == 0) || (diff_y == 0);
 }
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.101
diff -u -r1.101 map.h
--- common/map.h        2001/10/30 10:59:20     1.101
+++ common/map.h        2001/11/01 14:09:30
@@ -183,8 +183,6 @@
 char *map_get_tile_fpt_text(int x, int y);
 struct tile *map_get_tile(int x, int y);
 
-int xdist(int x0, int x1);
-int ydist(int y0, int y1);
 int map_distance(int x0, int y0, int x1, int y1);
 int real_map_distance(int x0, int y0, int x1, int y1);
 int sq_map_distance(int x0, int y0, int x1, int y1);
@@ -284,6 +282,7 @@
 
 int normalize_map_pos(int *x, int *y);
 void nearest_real_pos(int *x, int *y);
+int base_real_map_distance(int *dx, int *dy, int x0, int y0, int x1, int y1);
 
 void rand_neighbour(int x0, int y0, int *x, int *y);
 void rand_map_pos(int *x, int *y);
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.122
diff -u -r1.122 gotohand.c
--- server/gotohand.c   2001/10/08 12:11:17     1.122
+++ server/gotohand.c   2001/11/01 14:09:32
@@ -414,17 +414,7 @@
 {
   int diff_x, diff_y, dx, dy, scalar_product;
 
-  if (dest_x > src_x) {
-    diff_x = dest_x - src_x < map.xsize / 2 ? 1 : -1;
-  } else if (dest_x < src_x) {
-    diff_x = src_x - dest_x < map.xsize / 2 ? -1 : 1;
-  } else {                     /* dest_x == src_x */
-    diff_x = 0;
-  }
-  if (dest_y != src_y)
-    diff_y = dest_y > src_y ? 1 : -1;
-  else
-    diff_y = 0;
+  base_real_map_distance(&diff_x, &diff_y, src_x, src_y, dest_x, dest_y);
 
   DIRSTEP(dx, dy, dir);
   scalar_product = diff_x * dx + diff_y * dy;
@@ -443,23 +433,19 @@
 static int straightest_direction(int src_x, int src_y, int dest_x, int dest_y)
 {
   int best_dir;
-  int go_x, go_y;
+  int diff_x, diff_y;
 
-  /* Should we go up or down, east or west: go_x/y is the "step" in x/y.
-     Will allways be -1 or 1 even if src_x == dest_x or src_y == dest_y. */
-  go_x = dest_x > src_x ?
-    (dest_x-src_x < map.xsize/2 ? 1 : -1) :
-    (src_x-dest_x < map.xsize/2 ? -1 : 1);
-  go_y = dest_y > src_y ? 1 : -1;
-
-  if (src_x == dest_x)
-    best_dir = (go_y > 0) ? 6 : 1;
-  else if (src_y == dest_y)
-    best_dir = (go_x > 0) ? 4 : 3;
-  else if (go_x > 0)
-    best_dir = (go_y > 0) ? 7 : 2;
-  else /* go_x < 0 */
-    best_dir = (go_y > 0) ? 5 : 0;
+  /* Should we go up or down, east or west: diff_x/y is the "step" in x/y. */
+  base_real_map_distance(&diff_x, &diff_y, src_x, src_y, dest_x, dest_y);
+
+  if (!diff_x)
+    best_dir = (diff_y > 0) ? DIR8_SOUTH : DIR8_NORTH;
+  else if (!diff_y)
+    best_dir = (diff_x > 0) ? DIR8_EAST : DIR8_WEST;
+  else if (diff_x > 0)
+    best_dir = (diff_y > 0) ? DIR8_SOUTHEAST : DIR8_NORTHEAST;
+  else /* diff_x < 0 */
+    best_dir = (diff_y > 0) ? DIR8_SOUTHWEST : DIR8_NORTHWEST;
 
   return (best_dir);
 }
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.112
diff -u -r1.112 settlers.c
--- server/settlers.c   2001/10/14 21:02:17     1.112
+++ server/settlers.c   2001/11/01 14:09:33
@@ -769,8 +769,8 @@
   for (i = 0; i < game.nplayers; i++) {
     city_list_iterate(game.players[i].cities, pcity) {
       if (map_distance(x, y, pcity->x, pcity->y)<=8) {
-        dx = xdist(pcity->x, x);
-        dy = ydist(pcity->y, y);
+       base_real_map_distance(&dx, &dy, pcity->x, pcity->y, x, y);
+       dx = abs(dx), dy = abs(dy);
        /* these are heuristics... */
         if (dx<=5 && dy<5)
           return 0;

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