Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] example patch: [xy]_map_iterate
Home

[Freeciv-Dev] example patch: [xy]_map_iterate

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] example patch: [xy]_map_iterate
From: Jason Dorje Short <vze2zq63@xxxxxxxxxxx>
Date: Thu, 04 Oct 2001 05:57:09 -0400
Reply-to: jdorje@xxxxxxxxxxxx

There's a lot of code that can't use whole_map_iterate because the
iteration has to happen in a certain order.

I propose to use a new set of iterators to handle these iterations.  To
begin with, we'll have [xy]_map_iterate which will iterate over the
*full range* of [xy] values.  With the current rectangular map this is
simple enough, but say we had an isometric map:

  0 1 2 3 4
0     X
1   X X X
2 X X X X X
3   X X X
4     X

Each of x_map_iterate and y_map_iterate would iterate from 0 to 4.

(Note: I'm not sure of the nomenclature here.  Are these names okay?)

In many cases we might then want another pair of iterators, for instance
yx_map_iterate(y,x_itr) will iterate over the full set of x coordinates
for the given set of y coordinates (here the naming becomes even
harder).  For this patch, though, I've just handled a couple cases where
we iterate over the entire rectangle (in the above case [0..4]x[0..4])
and do a check for is_normal_map_pos to determine how to handle things
[1].  The associated code segments, therefore, should work with any
possible topology assuming x_map_iterate, y_map_iterate, and
is_normal_map_pos [2] are set up correctly.

Frankly, I like it a lot.

Other code will need additional filters to work: for instance the
polar-specific code will require that "polar" regions be defined
appropriately for the current map, while other iterators skip border
positions (currently the far poles) or border-to-border positions (the
two tiles near the poles).  All of this is reasonable for arbitrary
topologies.

Note that there's still good reason to use map_pos_to_index and
index_to_map_pos; whether whole_map_iterate uses this or the
[xy]_map_iterate iterators is a matter of taste.

[1] Incidentally, this provides a real use for the is_normal_map_pos
function.

[2] is_normal_map_pos is not included in the patch (sold separately).

jason
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.94
diff -u -r1.94 map.h
--- common/map.h        2001/09/27 22:49:53     1.94
+++ common/map.h        2001/10/04 09:40:25
@@ -413,6 +413,36 @@
   }                                                                           \
 }
 
+/* Iterates over all possible x values.  For our current rectangular
+   topology, this is simple enough, but for say an isometric rectangle:
+             X
+            XXX
+           XXXXX
+            XXX
+             X
+   each x value would have a different possible range of y values.  --JDS */
+#define x_map_iterate(x_itr)                                                  \
+{                                                                             \
+  int x_itr;                                                                  \
+  for (x_itr = 0; x_itr < map.xsize; x_itr++) {
+
+#define x_map_iterate_end                                                     \
+  }                                                                           \
+}
+
+/* Like x_map_iterate, but for the y coordinate */
+#define y_map_iterate(y_itr)                                                  \
+{                                                                             \
+  int y_itr;                                                                  \
+  for (y_itr = 0; y_itr < map.ysize; y_itr++) {
+
+#define y_map_iterate_end                                                     \
+  }                                                                           \
+}
+
+/* TODO: iterators that iterate over the y range given an x value and vice
+   versa.  But what should they be called?  --JDS */
+
 /* iterating y, x for cache efficiency */
 #define whole_map_iterate(WMI_x_itr, WMI_y_itr)                               \
 {                                                                             \
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.109
diff -u -r1.109 game.c
--- common/game.c       2001/09/25 19:58:13     1.109
+++ common/game.c       2001/10/04 09:40:26
@@ -109,12 +109,16 @@
 **************************************************************************/
 static void print_landarea_map(struct claim_map *pcmap, int turn)
 {
-  int x, y, p;
+  int p;
 
   if (turn == 0) {
     putchar ('\n');
   }
 
+  /* we can't assume we're on a rectangular map.  So, we iterate
+     over the rectangle surrounding the map and just draw
+     the map area itself (the rest is blank).  --JDS */
+
   if (turn == 0)
     {
       printf ("Player Info...\n");
@@ -122,78 +126,81 @@
       for (p = 0; p < game.nplayers; p++)
        {
          printf (".know (%d)\n  ", p);
-         for (x = 0; x < map.xsize; x++)
-           {
+         x_map_iterate(x) {
              printf ("%d", x % 10);
-           }
+         } x_map_iterate_end;
          putchar ('\n');
-         for (y = 0; y < map.ysize; y++)
-           {
+          y_map_iterate(y) {
              printf ("%d ", y % 10);
-             for (x = 0; x < map.xsize; x++)
-               {
+             x_map_iterate(x) {
+                if (is_normal_map_pos(x, y) {
                  printf ("%c",
-                         (pcmap->claims[map_inx(x,y)].know & (1u << p)) ?
+                          (pcmap->claims[map_inx(x,y)].know & (1u << p)) ?
                          'X' :
                          '-');
+               } else {
+                 printf (" ");
                }
+             } x_map_iterate_end;
              printf (" %d\n", y % 10);
-           }
+         } y_map_iterate_end;
 
          printf (".cities (%d)\n  ", p);
-         for (x = 0; x < map.xsize; x++)
-           {
+         x_map_iterate(x) {
              printf ("%d", x % 10);
-           }
+         } x_map_iterate_end;
          putchar ('\n');
-         for (y = 0; y < map.ysize; y++)
-           {
+         y_map_iterate(y) {
              printf ("%d ", y % 10);
-             for (x = 0; x < map.xsize; x++)
-               {
+             x_map_iterate(x) {
+               if (is_normal_map_pos(x, y) {
                  printf ("%c",
                          (pcmap->claims[map_inx(x,y)].cities & (1u << p)) ?
                          'O' :
                          '-');
+               } else {
+                 printf (" ");
                }
+             } x_map_iterate_end;
              printf (" %d\n", y % 10);
-           }
+         } y_map_iterate_end;
        }
     }
 
   printf ("Turn %d (%c)...\n", turn, when_char (turn));
 
   printf (".whom\n  ");
-  for (x = 0; x < map.xsize; x++)
-    {
+  x_map_iterate(x) {
       printf ("%d", x % 10);
-    }
+  } x_map_iterate_end(x)
   putchar ('\n');
-  for (y = 0; y < map.ysize; y++)
-    {
+  y_map_iterate(y) {
       printf ("%d ", y % 10);
-      for (x = 0; x < map.xsize; x++)
-       {
+      x_map_iterate(x) {
+       if (is_normal_map_pos(x, y) {
          printf ("%X", pcmap->claims[map_inx(x,y)].whom);
-       }
+       } else {
+         printf (" "); /* FIXME: wrong spacing */
+      } x_map_iterate_end(x)
       printf (" %d\n", y % 10);
-    }
+  } y_map_iterate_end;
 
   printf (".when\n  ");
-  for (x = 0; x < map.xsize; x++)
-    {
+  x_map_iterate(x) {
       printf ("%d", x % 10);
-    }
+  } x_map_iterate_end;
   putchar ('\n');
-  for (y = 0; y < map.ysize; y++)
-    {
+  y_map_iterate(y) {
       printf ("%d ", y % 10);
-      for (x = 0; x < map.xsize; x++)
-       {
+      x_map_iterate(x) {
+       if (is_normal_map_pos(x, y)) {
          printf ("%c", when_char (pcmap->claims[map_inx(x,y)].when));
+       } else {
+         printf (" ");
        }
+      } x_map_iterate_end;
       printf (" %d\n", y % 10);
-    }
+  } y_map_iterate_end;
 }
 
 #endif
Index: server/gamelog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamelog.c,v
retrieving revision 1.14
diff -u -r1.14 gamelog.c
--- server/gamelog.c    2001/01/13 13:43:38     1.14
+++ server/gamelog.c    2001/10/04 09:40:26
@@ -86,15 +86,18 @@
 
 void gamelog_map(void)
 {
-  int x, y;
   char *hline = fc_calloc(map.xsize+1,sizeof(char));
 
-  for (y=0;y<map.ysize;y++) {
-    for (x=0;x<map.xsize;x++) {
-      hline[x] = (map_get_terrain(x,y)==T_OCEAN) ? ' ' : '.';
-    }
+  y_map_iterate(y) {
+    x_map_iterate(x) {
+      if (is_normal_map_pos(x, y)) {
+        hline[x] = (map_get_terrain(x,y)==T_OCEAN) ? ' ' : '.';
+      } else {
+        hline[x] = '*'; /* fill in void tiles with asterisks (?) */
+      }
+    } x_map_iterate_end;
     gamelog(GAMELOG_MAP,"%s",hline);
-  }
+  } y_map_iterate_end;
   free(hline);
 }
 

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