[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]
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);
|
|