Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2003:
[Freeciv-Dev] (PR#6844) rand_map_pos_filtered
Home

[Freeciv-Dev] (PR#6844) rand_map_pos_filtered

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#6844) rand_map_pos_filtered
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 12 Nov 2003 14:29:12 -0800
Reply-to: rt@xxxxxxxxxxx

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

This patch adds a new function rand_map_pos_filtered, formerly of 
PR#6183 fame.  It has no users at this point, but I suspect we will 
eventually want it.

jason

Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.143
diff -u -r1.143 map.c
--- common/map.c        2003/09/19 13:17:12     1.143
+++ common/map.c        2003/09/22 05:04:22
@@ -1462,6 +1462,51 @@
 }
 
 /**************************************************************************
+ Random square anywhere on the map for which the 'filter' function
+ returns true.  return FALSE if none can be found.
+**************************************************************************/
+bool rand_map_pos_filtered(int *x, int *y, bool (*filter)(int x, int y))
+{
+  int tries = 0, count = 0;
+  const int max_tries = map.xsize * map.ysize / 10;
+
+  /* First do a few quick checks to find a spot. */
+  do {
+    index_to_map_pos(x, y, myrand(map.xsize * map.ysize));
+  } while (!filter(*x, *y) && ++tries < max_tries);
+  if (tries < max_tries) {
+    return TRUE;
+  }
+
+  /* If that fails, count all available spots and pick one.
+   * Slow but reliable. */
+  whole_map_iterate(x1, y1) {
+    if (filter(x1, y1)) {
+      count++;
+    }
+  } whole_map_iterate_end;
+
+  if (count == 0) {
+    return FALSE;
+  }
+
+  count = myrand(count);
+  whole_map_iterate(x1, y1) {
+    if (filter(x1, y1)) {
+      if (count == 0) {
+       *x = x1;
+       *y = y1;
+       return TRUE;
+      }
+      count--;
+    }
+  } whole_map_iterate_end;
+
+  assert(0);
+  return FALSE;
+}
+
+/**************************************************************************
 Return the debugging name of the direction.
 **************************************************************************/
 const char *dir_get_name(enum direction8 dir)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.153
diff -u -r1.153 map.h
--- common/map.h        2003/09/19 13:17:12     1.153
+++ common/map.h        2003/09/22 05:04:22
@@ -315,6 +315,7 @@
 
 void rand_neighbour(int x0, int y0, int *x, int *y);
 void rand_map_pos(int *x, int *y);
+bool rand_map_pos_filtered(int *x, int *y, bool (*filter)(int x, int y));
 
 bool is_water_adjacent_to_tile(int x, int y);
 bool is_tiles_adjacent(int x0, int y0, int x1, int y1);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#6844) rand_map_pos_filtered, Jason Short <=