Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2003:
[Freeciv-Dev] Re: (PR#3776) Goto sees ZOC but ignores it
Home

[Freeciv-Dev] Re: (PR#3776) Goto sees ZOC but ignores it

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: ChrisK@xxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#3776) Goto sees ZOC but ignores it
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxx>
Date: Wed, 16 Jul 2003 15:57:55 -0700
Reply-to: rt@xxxxxxxxxxxxxx

On Wed, 16 Jul 2003, Jason Short wrote:

> OK, I see.  Now I understand what the problem was originally...
> 
> However, this solution is incomplete.  Now for the client goto map we 
> check ZOC.  But any other PF in the client (that uses 
> simple_path_unit_iterator) will still use the server's version by default.
> 
> In other words, the server implementation should be in the server not in 
> the common code.  One alternative might be to have the common-code 
> implementation work for both server and client.  This would be ugly 
> (checking is_server) but at least it would be localized.

Attached is a version that still uses callbacks (maybe useful later), but
so far there is only one such callback: is_my_zoc in 
common/unit.c,suitably peppered with is_server checks.

G.

Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.176
diff -u -r1.176 unit.c
--- common/unit.c       2003/07/02 16:48:55     1.176
+++ common/unit.c       2003/07/16 22:54:54
@@ -1145,20 +1145,41 @@
 }
 
 /**************************************************************************
-  Is this square controlled by the unit's owner?
+  Is this square controlled by the pplayer?
 
-  Here "is_my_zoc" means essentially a square which is
-  *not* adjacent to an enemy unit on a land tile.
-  (Or, currently, an enemy city even if empty.)
+  Here "is_my_zoc" means essentially a square which is *not* adjacent to an
+  enemy unit on a land tile.
 
   Note this function only makes sense for ground units.
+
+  Since this function is also used in the client, it has to deal with some
+  client-specific features, like FoW and the fact that the client cannot 
+  see units inside enemy cities.
 **************************************************************************/
-bool is_my_zoc(struct player *unit_owner, int x0, int y0)
+bool is_my_zoc(struct player *pplayer, int x0, int y0)
 {
   square_iterate(x0, y0, 1, x1, y1) {
-    if (!is_ocean(map_get_terrain(x1, y1))
-       && is_non_allied_unit_tile(map_get_tile(x1, y1), unit_owner))
+    struct tile *ptile = map_get_tile(x1, y1);
+    
+    if (is_ocean(ptile->terrain)) {
+      continue;
+    }
+    if (is_non_allied_unit_tile(ptile, pplayer)) {
+      /* Note: in the client, the above function will return NULL 
+       * if there is a city there, even if the city is occupied */
       return FALSE;
+    }
+    
+    if (!is_server) {
+      struct city *pcity = is_non_allied_city_tile(ptile, pplayer);
+
+      if (pcity 
+          && (pcity->occupied 
+              || map_get_known2(x1, y1, pplayer) == TILE_KNOWN_FOGGED)) {
+        /* If the city is fogged, we assume it's occupied */
+        return FALSE;
+      }
+    }
   } square_iterate_end;
 
   return TRUE;
Index: common/aicore/path_finding.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.c,v
retrieving revision 1.9
diff -u -r1.9 path_finding.c
--- common/aicore/path_finding.c        2003/05/03 13:28:48     1.9
+++ common/aicore/path_finding.c        2003/07/16 22:54:55
@@ -205,17 +205,18 @@
     node->behavior = TB_NORMAL;
   }
 
-  if (params->zoc_used) {
+  if (params->get_zoc) {
     struct tile *tile = map_get_tile(x, y);
     bool my_zoc = (tile->city || tile->terrain == T_OCEAN
-                  || is_my_zoc(params->owner, x, y));
-    bool allied = (is_allied_unit_tile(tile, params->owner) != NULL);
-    bool enemy = (is_enemy_unit_tile(tile, params->owner) != NULL);
-
-    /* if my zoc 2 else if allied 1 else 0 */
-    /* Essentially, enemy tile is like allied tile, we should be allowed
-     * to go there (attack), but not to leave, necessarily */
-    node->zoc_number = (my_zoc ? 2 : ((allied || enemy) ? 1 : 0));
+                  || params->get_zoc(params->owner, x, y));
+    /* ZoC rules cannot prevent us from moving into/attacking an occupied 
+     * tile.  Other rules can, but we don't care about them here. */ 
+    bool occupied = (unit_list_size(&(map_get_tile(x, y)->units)) > 0
+                     || map_get_city(x, y));
+
+    /* 2 means can move unrestricted from/into it, 
+     * 1 means can move unrestricted into it, but not necessarily from it */
+    node->zoc_number = (my_zoc ? 2 : (occupied ? 1 : 0));
   }
 
   /* Evaluate the extra cost of the destination */
@@ -279,7 +280,7 @@
       }
 
       /* Is the move ZOC-ok? */
-      if (pf_map->params->zoc_used
+      if (pf_map->params->get_zoc
          && !(node->zoc_number > 1 || node1->zoc_number > 0)) {
        continue;
       }
@@ -834,7 +835,7 @@
       }
 
       /* Is the move ZOC-ok? */
-      if (pf_map->params->zoc_used
+      if (pf_map->params->get_zoc
          && !(node->zoc_number > 1 || node1->zoc_number > 2)) {
        continue;
       }
Index: common/aicore/path_finding.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/path_finding.h,v
retrieving revision 1.2
diff -u -r1.2 path_finding.h
--- common/aicore/path_finding.h        2003/04/04 15:47:49     1.2
+++ common/aicore/path_finding.h        2003/07/16 22:54:55
@@ -125,8 +125,9 @@
  * we won't be able to leave (at least alive).
  * 
  * There are few other options in the path-finding, including "omniscience" 
- * (if true, all tiles are assumed to be KNOWN) and "zoc_used" (if true, we 
- * will consider restrictions imposed by zones of control upon our movements).
+ * (if true, all tiles are assumed to be KNOWN) and "get_zoc" callback (if 
+ * not NULL, we will consider restrictions imposed upon our movements by 
+ * zones of control).
  *
  *  
  * FORMULAE:
@@ -298,7 +299,6 @@
 
   struct player *owner;
 
-  bool zoc_used;               /* Do we care about zones of control? */
   bool omniscience;            /* Do we care if the tile is visible? */
 
   enum turn_mode turn_mode;    /* See definitions. */
@@ -323,11 +323,20 @@
   int (*get_EC) (int x, int y, enum known_type known,
                 struct pf_parameter * param);
 
+  /* Although the rules governing ZoC are universal, the amount of
+   * information available at server and client is different. To 
+   * compensate for it, we might need to supply our own version 
+   * of "common" is_my_zoc.  Also AI might need to partially ignore 
+   * ZoC for strategic planning purposes (take into account enemy cities 
+   * but not units for example).
+   * If this callback is NULL, ZoC are ignored.*/
+  bool (*get_zoc) (struct player *pplayer, int x, int y);
+
   /* If this callback is non-NULL and returns TRUE this position is
    * dangerous. The unit will never end a turn at a dangerous
    * position. Can be NULL. */
-   bool(*is_pos_dangerous) (int x, int y, enum known_type,
-                           struct pf_parameter * param);
+  bool (*is_pos_dangerous) (int x, int y, enum known_type,
+                            struct pf_parameter * param);
 
   /* User provided data. Can be used to attach arbitrary information
    * to the map. */
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.2
diff -u -r1.2 pf_tools.c
--- common/aicore/pf_tools.c    2003/05/15 12:38:11     1.2
+++ common/aicore/pf_tools.c    2003/07/16 22:54:55
@@ -283,8 +283,12 @@
     die("unknown move_type");
   }
 
-  parameter->zoc_used = (unit_type(punit)->move_type == LAND_MOVING
-                        && !unit_flag(punit, F_IGZOC));
+  if (unit_type(punit)->move_type == LAND_MOVING 
+      && !unit_flag(punit, F_IGZOC)) {
+    parameter->get_zoc = is_my_zoc;
+  } else {
+    parameter->get_zoc = NULL;
+  }
 
   if (unit_flag(punit, F_TRIREME)
       && base_trireme_loss_pct(unit_owner(punit)) > 0) {
@@ -323,7 +327,7 @@
     die("Unsupported move_type");
   }
 
-  parameter->zoc_used = FALSE;
+  parameter->get_zoc = NULL;
 
   if (unit_flag(punit, F_TRIREME)
       && base_trireme_loss_pct(unit_owner(punit)) > 0) {

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