Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2001:
[Freeciv-Dev] Re: buglet in normalization in init_new_game() (PR#1063)
Home

[Freeciv-Dev] Re: buglet in normalization in init_new_game() (PR#1063)

[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] Re: buglet in normalization in init_new_game() (PR#1063)
From: jdorje@xxxxxxxxxxxxxxxxxxxxx
Date: Fri, 30 Nov 2001 14:51:48 -0800 (PST)

jdorje@xxxxxxxxxxxxxxxxxxxxx wrote:

Raimar Falke wrote:


IMHO it looks like a job for a new circle_iterate.


The attached patch is an adequate implementation of circle_iterate
(actually, I'm not happy with the use of sqrt() but I'm not sure how to
do without it),


This is an updated patch that implements both square_dxy_iterate and circle_iterate (which is a simple wrapper to square_dxy_iterate). Hopefully this will make Gaute happy by providing the square_dxy_iterate macro (which we both agree is useful).

I do think that circle_iterate should be a macro even if it's only used once. But I also think more uses will be found for it - as I explained in my other patch.

square_iterate could also be written as a macro to square_dxy_iterate, but there might be an efficiency drop (not sure about this), so I haven't done this.

jason
? diff
? old
? topology
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.104
diff -u -r1.104 map.h
--- common/map.h        2001/11/23 17:27:08     1.104
+++ common/map.h        2001/11/30 22:23:55
@@ -13,7 +13,9 @@
 #ifndef FC__MAP_H
 #define FC__MAP_H
 
-#include "assert.h"
+#include <assert.h>
+#include <math.h>
+
 #include "player.h"
 #include "terrain.h"
 #include "unit.h"
@@ -417,9 +419,32 @@
 }
 
 /* Iterate through all tiles in a square with given center and radius.
+   A position (x_itr, y_itr) that is returned will be normalized; unreal
+   positions will be automatically discarded.  (dx_itr, dy_itr) is the
+   standard distance vector between the position and the center position.  
+   Note that when the square is larger than the map the distance vector may 
+   not be the minimum distance vector. */
+#define square_dxy_iterate(center_x, center_y, radius, x_itr, y_itr,          \
+                           dx_itr, dy_itr)                                    \
+{                                                                             \
+  int _center_x = (center_x), _center_y = (center_y), _radius = (radius);     \
+  int dx_itr, dy_itr;                                                         \
+  CHECK_MAP_POS(_center_x, _center_y);                                        \
+  for (dy_itr = -_radius; dy_itr <= _radius; dy_itr++)                        \
+    for (dx_itr = -_radius; dx_itr <= _radius; dx_itr++) {                    \
+      int x_itr = dx_itr + _center_x, y_itr = dy_itr + _center_y;             \
+      if (normalize_map_pos(&x_itr, &y_itr)) {                         
+
+#define square_dxy_iterate_end                                                \
+      }                                                                       \
+    }                                                                         \
+}
+
+/* Iterate through all tiles in a square with given center and radius.
    Positions returned will have adjusted x, and positions with illegal y will 
be
    automatically discarded.
  */
+/* Note: this could be rewriten as a wrapper to square_dxy_iterate. */
 #define square_iterate(SI_center_x, SI_center_y, radius, SI_x_itr, SI_y_itr)  \
 {                                                                             \
   int SI_x_itr, SI_y_itr;                                                     \
@@ -437,6 +462,21 @@
     }                                                                         \
   }                                                                           \
 }
+
+/* Iterate through all tiles in a circle with given center and squared
+   radius.  Positions returned will have adjusted (x, y); unreal positions
+   will be automatically discarded. */
+#define circle_iterate(center_x, center_y, sq_radius, x_itr, y_itr)           \
+{                                                                             \
+  int _sq_radius = (sq_radius), _cr_radius = (int)sqrt(_sq_radius);           \
+  square_dxy_iterate(center_x, center_y, _cr_radius,                          \
+                    x_itr, y_itr, _dx, _dy) {                                \
+    if (_dy * _dy + _dx * _dx <= _sq_radius) {
+
+#define circle_iterate_end                                                    \
+    }                                                                         \
+  } square_dxy_iterate_end;                                                   \
+}                                                                             
 
 /* Iterate through all tiles adjacent to a tile */
 #define adjc_iterate(RI_center_x, RI_center_y, RI_x_itr, RI_y_itr)            \
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.98
diff -u -r1.98 gamehand.c
--- server/gamehand.c   2001/10/18 16:45:34     1.98
+++ server/gamehand.c   2001/11/30 22:23:55
@@ -35,7 +35,7 @@
 void init_new_game(void)
 {
   int i, j, x, y;
-  int vx, vy, dx, dy;
+  int dx, dy;
   Unit_Type_id utype;
   int start_pos[MAX_NUM_PLAYERS]; /* indices into map.start_positions[] */
 
@@ -130,16 +130,9 @@
                game.players[i].name);
       }
       /* Expose visible area. */
-      for (vx = 1; (vx * vx) <= game.rgame.init_vis_radius_sq; vx++) {
-       for (vy = 1; (vy * vy) <= game.rgame.init_vis_radius_sq; vy++) {
-         if (((vx *vx) + (vy *vy)) <= game.rgame.init_vis_radius_sq) {
-           show_area(&game.players[i], dx-vx+1, dy-vy+1, 1);
-           show_area(&game.players[i], dx+vx-1, dy-vy+1, 1);
-           show_area(&game.players[i], dx-vx+1, dy+vy-1, 1);
-           show_area(&game.players[i], dx+vx-1, dy+vy-1, 1);
-         }
-       }
-      }
+      circle_iterate(dx, dy, game.rgame.init_vis_radius_sq, cx, cy) {
+       show_area(&game.players[i], cx, cy, 0);
+      } circle_iterate_end;
       /* Create the unit of an appropriate type. */
       utype = get_role_unit((j < game.settlers) ? F_CITIES : L_EXPLORER, 0);
       create_unit(&game.players[i], dx, dy, utype, 0, 0, -1);

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