Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2004:
[Freeciv-Dev] (PR#11126) unify map_get_known
Home

[Freeciv-Dev] (PR#11126) unify map_get_known

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11126) unify map_get_known
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 22 Nov 2004 14:06:19 -0800
Reply-to: rt@xxxxxxxxxxx

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

Updated patch.
? vgcore.pid14719
? vgcore.pid22960
Index: client/climap.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climap.c,v
retrieving revision 1.5
diff -u -r1.5 climap.c
--- client/climap.c     29 Sep 2004 02:24:19 -0000      1.5
+++ client/climap.c     21 Nov 2004 08:42:14 -0000
@@ -34,7 +34,7 @@
 *************************************************************************/
 enum known_type tile_get_known(const struct tile *ptile)
 {
-  return (enum known_type) ptile->known;
+  return map_get_known(ptile, game.player_ptr);
 }
 
 /**************************************************************************
Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.143
diff -u -r1.143 climisc.c
--- client/climisc.c    20 Oct 2004 04:34:27 -0000      1.143
+++ client/climisc.c    21 Nov 2004 08:42:14 -0000
@@ -955,16 +955,6 @@
   output_window_force_thaw();
 }
 
-/*************************************************************************
-...
-*************************************************************************/
-enum known_type map_get_known(const struct tile *ptile,
-                             struct player *pplayer)
-{
-  assert(pplayer == game.player_ptr);
-  return tile_get_known(ptile);
-}
-
 /**************************************************************************
   Find city nearest to given unit and optionally return squared city
   distance Parameter sq_dist may be NULL. Returns NULL only if no city is
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.160
diff -u -r1.160 mapview_common.c
--- client/mapview_common.c     15 Nov 2004 17:20:55 -0000      1.160
+++ client/mapview_common.c     21 Nov 2004 08:42:15 -0000
@@ -1462,7 +1462,7 @@
   int count = fill_sprite_array(tile_sprs, ptile,
                                get_drawable_unit(ptile, citymode),
                                ptile->city, citymode);
-  bool fog = ptile->known == TILE_KNOWN_FOGGED && draw_fog_of_war;
+  bool fog = tile_get_known(ptile) == TILE_KNOWN_FOGGED && draw_fog_of_war;
 
   /*** Draw terrain and specials ***/
   put_drawn_sprites(pcanvas, canvas_x, canvas_y, count, tile_sprs, fog);
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.421
diff -u -r1.421 packhand.c
--- client/packhand.c   20 Nov 2004 17:27:43 -0000      1.421
+++ client/packhand.c   21 Nov 2004 08:42:16 -0000
@@ -1933,7 +1933,7 @@
 void handle_tile_info(struct packet_tile_info *packet)
 {
   struct tile *ptile = map_pos_to_tile(packet->x, packet->y);
-  enum known_type old_known = ptile->known;
+  enum known_type old_known = tile_get_known(ptile);
   bool tile_changed = FALSE;
   bool known_changed = FALSE;
 
@@ -1958,10 +1958,25 @@
       tile_changed = TRUE;
     }
   }
-  if (ptile->known != packet->known) {
+  if (old_known != packet->known) {
     known_changed = TRUE;
   }
-  ptile->known = packet->known;
+  BV_CLR(ptile->tile_known, game.player_idx);
+  BV_CLR(ptile->tile_seen, game.player_idx);
+  switch (packet->known) {
+  case TILE_KNOWN:
+    BV_SET(ptile->tile_known, game.player_idx);
+    BV_SET(ptile->tile_seen, game.player_idx);
+    break;
+  case TILE_KNOWN_FOGGED:
+    BV_SET(ptile->tile_known, game.player_idx);
+    break;
+  case TILE_UNKNOWN:
+    break;
+  default:
+    freelog(LOG_NORMAL, "Unknown tile value %d.", packet->known);
+    break;
+  }
 
   if (packet->spec_sprite[0] != '\0') {
     if (!ptile->spec_sprite
@@ -1982,7 +1997,8 @@
 
   reset_move_costs(ptile);
 
-  if (ptile->known <= TILE_KNOWN_FOGGED && old_known == TILE_KNOWN) {
+  if (tile_get_known(ptile) <= TILE_KNOWN_FOGGED
+      && old_known == TILE_KNOWN) {
     /* This is an error.  So first we log the error, then make an assertion.
      * But for NDEBUG clients we fix the error. */
     unit_list_iterate(ptile->units, punit) {
@@ -2015,9 +2031,9 @@
      * A tile can only change if it was known before and is still
      * known. In the other cases the tile is new or removed.
      */
-    if (known_changed && ptile->known == TILE_KNOWN) {
+    if (known_changed && tile_get_known(ptile) == TILE_KNOWN) {
       agents_tile_new(ptile);
-    } else if (known_changed && ptile->known == TILE_KNOWN_FOGGED) {
+    } else if (known_changed && tile_get_known(ptile) == TILE_KNOWN_FOGGED) {
       agents_tile_remove(ptile);
     } else {
       agents_tile_changed(ptile);
@@ -2027,7 +2043,7 @@
   /* refresh tiles */
   if (can_client_change_view()) {
     /* the tile itself */
-    if (tile_changed || old_known!=ptile->known)
+    if (tile_changed || old_known != tile_get_known(ptile))
       refresh_tile_mapcanvas(ptile, FALSE);
 
     /* if the terrain or the specials of the tile
Index: common/map.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.c,v
retrieving revision 1.203
diff -u -r1.203 map.c
--- common/map.c        13 Nov 2004 08:34:17 -0000      1.203
+++ common/map.c        21 Nov 2004 08:42:17 -0000
@@ -355,7 +355,8 @@
 {
   ptile->terrain  = T_UNKNOWN;
   ptile->special  = S_NO_SPECIAL;
-  ptile->known    = 0;
+  BV_CLR_ALL(ptile->tile_known);
+  BV_CLR_ALL(ptile->tile_seen);
   ptile->continent = 0;
   ptile->city     = NULL;
   unit_list_init(&ptile->units);
@@ -1309,6 +1310,23 @@
   ptile->terrain = ter;
 }
 
+/*************************************************************************
+  Return a known_type enumeration value for the tile.
+
+  Note that the client only knows known data about game.player_ptr.
+*************************************************************************/
+enum known_type map_get_known(const struct tile *ptile,
+                             const struct player *pplayer)
+{
+  if (!BV_ISSET(ptile->tile_known, pplayer->player_no)) {
+    return TILE_UNKNOWN;
+  } else if (!BV_ISSET(ptile->tile_seen, pplayer->player_no)) {
+    return TILE_KNOWN_FOGGED;
+  } else {
+    return TILE_KNOWN;
+  }
+}
+
 /***************************************************************
 ...
 ***************************************************************/
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.225
diff -u -r1.225 map.h
--- common/map.h        13 Nov 2004 08:34:17 -0000      1.225
+++ common/map.h        21 Nov 2004 08:42:17 -0000
@@ -49,9 +49,7 @@
   enum tile_special_type special;
   struct city *city;
   struct unit_list units;
-  unsigned int known;   /* A bitvector on the server side, an
-                          enum known_type on the client side.
-                          Player_no is index */
+  player_bv tile_known, tile_seen;
   int assigned; /* these can save a lot of CPU usage -- Syela */
   struct city *worked;      /* city working tile, or NULL if none */
   Continent_id continent;
@@ -359,9 +357,8 @@
 bool is_real_map_pos(int x, int y);
 bool is_normal_map_pos(int x, int y);
 
-/* implemented in server/maphand.c and client/climisc.c */
 enum known_type map_get_known(const struct tile *ptile,
-                             struct player *pplayer);
+                             const struct player *pplayer);
 
 /* special testing */
 bool map_has_special(const struct tile *ptile,
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.132
diff -u -r1.132 player.h
--- common/player.h     17 Nov 2004 16:59:07 -0000      1.132
+++ common/player.h     21 Nov 2004 08:42:17 -0000
@@ -57,6 +57,8 @@
   H_DIPLOMACY = 2048  /* Not very good at diplomacy */
 };
 
+BV_DEFINE(player_bv, MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS);
+
 struct player_economic {
   int gold;
   int tax;
Index: server/maphand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.c,v
retrieving revision 1.150
diff -u -r1.150 maphand.c
--- server/maphand.c    15 Oct 2004 09:39:05 -0000      1.150
+++ server/maphand.c    21 Nov 2004 08:42:19 -0000
@@ -912,7 +912,7 @@
 ***************************************************************/
 bool map_is_known(const struct tile *ptile, struct player *pplayer)
 {
-  return TEST_BIT(ptile->known, pplayer->player_no);
+  return BV_ISSET(ptile->tile_known, pplayer->player_no);
 }
 
 /***************************************************************
@@ -920,8 +920,10 @@
 ***************************************************************/
 bool map_is_known_and_seen(const struct tile *ptile, struct player *pplayer)
 {
-  return TEST_BIT(ptile->known, pplayer->player_no)
-      && ((pplayer->private_map + ptile->index)->seen != 0);
+  assert(BV_ISSET(ptile->tile_seen, pplayer->player_no)
+        == (map_get_player_tile(ptile, pplayer)->seen_count > 0));
+  return (BV_ISSET(ptile->tile_known, pplayer->player_no)
+         && BV_ISSET(ptile->tile_seen, pplayer->player_no));
 }
 
 /***************************************************************
@@ -929,7 +931,9 @@
 ***************************************************************/
 static int map_get_seen(const struct tile *ptile, struct player *pplayer)
 {
-  return map_get_player_tile(ptile, pplayer)->seen;
+  assert(BV_ISSET(ptile->tile_seen, pplayer->player_no)
+        == (map_get_player_tile(ptile, pplayer)->seen_count > 0));
+  return map_get_player_tile(ptile, pplayer)->seen_count;
 }
 
 /***************************************************************
@@ -937,10 +941,16 @@
 ***************************************************************/
 void map_change_seen(struct tile *ptile, struct player *pplayer, int change)
 {
-  map_get_player_tile(ptile, pplayer)->seen += change;
+  struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
+
+  plrtile->seen_count += change;
+  if (plrtile->seen_count != 0) {
+    BV_SET(ptile->tile_seen, pplayer->player_no);
+  } else {
+    BV_CLR(ptile->tile_seen, pplayer->player_no);
+  }
   freelog(LOG_DEBUG, "%d,%d, p: %d, change %d, result %d\n", TILE_XY(ptile),
-         pplayer->player_no, change, map_get_player_tile(ptile,
-                                                        pplayer)->seen);
+         pplayer->player_no, change, plrtile->seen_count);
 }
 
 /***************************************************************
@@ -969,7 +979,7 @@
 ***************************************************************/
 void map_set_known(struct tile *ptile, struct player *pplayer)
 {
-  ptile->known |= (1u<<pplayer->player_no);
+  BV_SET(ptile->tile_known, pplayer->player_no);
 }
 
 /***************************************************************
@@ -977,7 +987,7 @@
 ***************************************************************/
 void map_clear_known(struct tile *ptile, struct player *pplayer)
 {
-  ptile->known &= ~(1u<<pplayer->player_no);
+  BV_CLR(ptile->tile_known, pplayer->player_no);
 }
 
 /***************************************************************
@@ -1057,18 +1067,20 @@
   plrtile->special = S_NO_SPECIAL;
   plrtile->city = NULL;
 
-  plrtile->seen = 0;
+  plrtile->seen_count = 0;
   plrtile->pending_seen = 0;
+  BV_CLR(ptile->tile_seen, pplayer->player_no);
   if (!game.fogofwar_old) {
     if (map_is_known(ptile, pplayer)) {
-      plrtile->seen = 1;
+      plrtile->seen_count = 1;
+      BV_SET(ptile->tile_seen, pplayer->player_no);
     } else {
       plrtile->pending_seen = 1;
     }
   }
 
   plrtile->last_updated = GAME_START_YEAR;
-  plrtile->own_seen = plrtile->seen;
+  plrtile->own_seen = plrtile->seen_count;
 }
  
 /***************************************************************
@@ -1358,23 +1370,6 @@
 /*************************************************************************
 ...
 *************************************************************************/
-enum known_type map_get_known(const struct tile *ptile,
-                             struct player *pplayer)
-{
-  if (map_is_known(ptile, pplayer)) {
-    if (map_get_seen(ptile, pplayer) > 0) {
-      return TILE_KNOWN;
-    } else {
-      return TILE_KNOWN_FOGGED;
-    }
-  } else {
-    return TILE_UNKNOWN;
-  }
-}
-
-/*************************************************************************
-...
-*************************************************************************/
 static void enable_fog_of_war_player(struct player *pplayer)
 {
   whole_map_iterate(ptile) {
Index: server/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.50
diff -u -r1.50 maphand.h
--- server/maphand.h    11 Nov 2004 16:50:54 -0000      1.50
+++ server/maphand.h    21 Nov 2004 08:42:19 -0000
@@ -38,7 +38,7 @@
 struct player_tile {
   Terrain_type_id terrain;
   enum tile_special_type special;
-  unsigned short seen;
+  unsigned short seen_count;
   unsigned short own_seen;
   /* If you build a city with an unknown square within city radius
      the square stays unknown. However, we still have to keep count
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.54
diff -u -r1.54 sanitycheck.c
--- server/sanitycheck.c        30 Oct 2004 11:46:11 -0000      1.54
+++ server/sanitycheck.c        21 Nov 2004 08:42:19 -0000
@@ -66,11 +66,17 @@
     players_iterate(pplayer) {
       struct player_tile *plr_tile = map_get_player_tile(ptile, pplayer);
       /* underflow of unsigned int */
-      assert(plr_tile->seen < 60000);
+      assert(plr_tile->seen_count < 60000);
       assert(plr_tile->own_seen < 60000);
       assert(plr_tile->pending_seen < 60000);
 
-      assert(plr_tile->own_seen <= plr_tile->seen);
+      if (plr_tile->seen_count > 0) {
+       assert(BV_ISSET(ptile->tile_seen, pplayer->player_no));
+      } else {
+       assert(!BV_ISSET(ptile->tile_seen, pplayer->player_no));
+      }
+
+      assert(plr_tile->own_seen <= plr_tile->seen_count);
       if (map_is_known(ptile, pplayer)) {
        assert(plr_tile->pending_seen == 0);
       }
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.207
diff -u -r1.207 savegame.c
--- server/savegame.c   20 Nov 2004 18:08:42 -0000      1.207
+++ server/savegame.c   21 Nov 2004 08:42:19 -0000
@@ -617,36 +617,48 @@
                ptile->special |= ascii_hex2bin(ch, 3));
 
   if (secfile_lookup_bool_default(file, TRUE, "game.save_known")) {
+    int known[MAX_MAP_INDEX];
 
     /* get 4-bit segments of the first half of the 32-bit "known" field */
     LOAD_MAP_DATA(ch, nat_y, ptile,
                  secfile_lookup_str(file, "map.a%03d", nat_y),
-                 ptile->known = ascii_hex2bin(ch, 0));
+                 known[ptile->index] = ascii_hex2bin(ch, 0));
     LOAD_MAP_DATA(ch, nat_y, ptile,
                  secfile_lookup_str(file, "map.b%03d", nat_y),
-                 ptile->known |= ascii_hex2bin(ch, 1));
+                 known[ptile->index] |= ascii_hex2bin(ch, 1));
     LOAD_MAP_DATA(ch, nat_y, ptile,
                  secfile_lookup_str(file, "map.c%03d", nat_y),
-                 ptile->known |= ascii_hex2bin(ch, 2));
+                 known[ptile->index] |= ascii_hex2bin(ch, 2));
     LOAD_MAP_DATA(ch, nat_y, ptile,
                  secfile_lookup_str(file, "map.d%03d", nat_y),
-                 ptile->known |= ascii_hex2bin(ch, 3));
+                 known[ptile->index] |= ascii_hex2bin(ch, 3));
 
     if (has_capability("known32fix", savefile_options)) {
       /* get 4-bit segments of the second half of the 32-bit "known" field */
       LOAD_MAP_DATA(ch, nat_y, ptile,
                    secfile_lookup_str(file, "map.e%03d", nat_y),
-                   ptile->known |= ascii_hex2bin(ch, 4));
+                   known[ptile->index] |= ascii_hex2bin(ch, 4));
       LOAD_MAP_DATA(ch, nat_y, ptile,
                    secfile_lookup_str(file, "map.g%03d", nat_y),
-                   ptile->known |= ascii_hex2bin(ch, 5));
+                   known[ptile->index] |= ascii_hex2bin(ch, 5));
       LOAD_MAP_DATA(ch, nat_y, ptile,
                    secfile_lookup_str(file, "map.h%03d", nat_y),
-                   ptile->known |= ascii_hex2bin(ch, 6));
+                   known[ptile->index] |= ascii_hex2bin(ch, 6));
       LOAD_MAP_DATA(ch, nat_y, ptile,
                    secfile_lookup_str(file, "map.i%03d", nat_y),
-                   ptile->known |= ascii_hex2bin(ch, 7));
+                   known[ptile->index] |= ascii_hex2bin(ch, 7));
     }
+
+    /* HACK: we read the known data from hex into a 32-bit integer, and
+     * now we convert it to player_bv. */
+    whole_map_iterate(ptile) {
+      BV_CLR_ALL(ptile->tile_known);
+      players_iterate(pplayer) {
+       if (known[ptile->index] & (1u << pplayer->player_no)) {
+         BV_SET(ptile->tile_known, pplayer->player_no);
+       }
+      } players_iterate_end;
+    } whole_map_iterate_end;
   }
 
 
@@ -712,27 +724,40 @@
 
   secfile_insert_bool(file, game.save_options.save_known, "game.save_known");
   if (game.save_options.save_known) {
+    int known[MAX_MAP_INDEX];
+
     /* put the top 4 bits (bits 12-15) of special flags */
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.f%03d",
                         bin2ascii_hex(ptile->special, 3));
 
+    /* HACK: we convert the data into a 32-bit integer, and then save it as
+     * hex. */
+    memset(known, 0, sizeof(known));
+    whole_map_iterate(ptile) {
+      players_iterate(pplayer) {
+       if (map_is_known(ptile, pplayer)) {
+         known[ptile->index] |= (1u << pplayer->player_no);
+       }
+      } players_iterate_end;
+    } whole_map_iterate_end;
+
     /* put 4-bit segments of the 32-bit "known" field */
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.a%03d",
-                        bin2ascii_hex(ptile->known, 0));
+                        bin2ascii_hex(known[ptile->index], 0));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.b%03d",
-                        bin2ascii_hex(ptile->known, 1));
+                        bin2ascii_hex(known[ptile->index], 1));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.c%03d",
-                        bin2ascii_hex(ptile->known, 2));
+                        bin2ascii_hex(known[ptile->index], 2));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.d%03d",
-                        bin2ascii_hex(ptile->known, 3));
+                        bin2ascii_hex(known[ptile->index], 3));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.e%03d",
-                        bin2ascii_hex(ptile->known, 4));
+                        bin2ascii_hex(known[ptile->index], 4));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.g%03d",
-                        bin2ascii_hex(ptile->known, 5));
+                        bin2ascii_hex(known[ptile->index], 5));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.h%03d",
-                        bin2ascii_hex(ptile->known, 6));
+                        bin2ascii_hex(known[ptile->index], 6));
     SAVE_NORMAL_MAP_DATA(ptile, file, "map.i%03d",
-                        bin2ascii_hex(ptile->known, 7));
+                        bin2ascii_hex(known[ptile->index], 7));
   }
 
   whole_map_iterate(ptile) {
Index: server/score.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/score.c,v
retrieving revision 1.8
diff -u -r1.8 score.c
--- server/score.c      29 Sep 2004 02:24:24 -0000      1.8
+++ server/score.c      21 Nov 2004 08:42:20 -0000
@@ -36,7 +36,7 @@
 struct claim_cell {
   int when;
   int whom;
-  int know;
+  player_bv know;
   int cities;
 };
 
@@ -199,7 +199,7 @@
       nextedge++;
       pcmap->player_landarea[owner]++;
       pcmap->player_owndarea[owner]++;
-      pclaim->know = ptile->known;
+      BV_COPY(pclaim->know, ptile->tile_known);
     } else if (ptile->worked) {
       owner = ptile->worked->owner;
       pclaim->when = turn + 1;
@@ -208,7 +208,7 @@
       nextedge++;
       pcmap->player_landarea[owner]++;
       pcmap->player_owndarea[owner]++;
-      pclaim->know = ptile->known;
+      BV_COPY(pclaim->know, ptile->tile_known);
     } else if (unit_list_size(&ptile->units) > 0) {
       owner = (unit_list_get(&ptile->units, 0))->owner;
       pclaim->when = turn + 1;
@@ -219,11 +219,11 @@
       if (TEST_BIT(pclaim->cities, owner)) {
        pcmap->player_owndarea[owner]++;
       }
-      pclaim->know = ptile->known;
+      BV_COPY(pclaim->know, ptile->tile_known);
     } else {
       /* pclaim->when = 0; */
       pclaim->whom = no_owner;
-      pclaim->know = ptile->known;
+      BV_COPY(pclaim->know, ptile->tile_known);
     }
   } whole_map_iterate_end;
 
@@ -260,7 +260,7 @@
          int j = tile1->index;
          struct claim_cell *pclaim = &pcmap->claims[j];
 
-         if (TEST_BIT(pclaim->know, owner)) {
+         if (BV_ISSET(pclaim->know, owner)) {
            if (pclaim->when == 0) {
              pclaim->when = turn + 1;
              pclaim->whom = owner;
Index: utility/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/shared.h,v
retrieving revision 1.137
diff -u -r1.137 shared.h
--- utility/shared.h    21 Oct 2004 20:27:29 -0000      1.137
+++ utility/shared.h    21 Nov 2004 08:42:20 -0000
@@ -185,6 +185,10 @@
 #define BV_ARE_EQUAL(vec1, vec2) \
   bv_are_equal((vec1).vec, (vec2).vec, sizeof((vec1).vec), sizeof((vec2).vec))
 
+#define BV_COPY(dst, src)                              \
+  (assert(sizeof((src).vec) == sizeof((dst).vec)),     \
+   memcpy((dst).vec, (src).vec, sizeof((dst).vec)))
+
 #define BV_DEFINE(name, bits) \
   typedef struct { unsigned char vec[_BV_BYTES(bits)]; } name
 

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