Complete.Org: Mailing Lists: Archives: freeciv-ai: May 2004:
[freeciv-ai] (PR#8827) bad use of ferries by AI
Home

[freeciv-ai] (PR#8827) bad use of ferries by AI

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Subject: [freeciv-ai] (PR#8827) bad use of ferries by AI
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxxx>
Date: Mon, 31 May 2004 12:13:29 -0700
Reply-to: rt@xxxxxxxxxxx

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

> [glip - Fri May 28 20:29:58 2004]:
>
> I run some games.  It's hard to pinpoint what exactly is wrong with
> ferries, but they do behave in an erratic manner.  But I found one
> mistake, ferries dumped by their prospective passengers were not made
> immediately available.  A patch is attached.  Please commit.
> 
> There are many other improvements which need to be done:
> 1. make settler and military building code use find_ferry and not
> find_boat which doesn't find boats.  Then they will not ask for more 
> boats.
> 2. make ferryboats which go to a city actually coordinate their 
> efforts

While observing new settlers I discovered some more bugs in the ferry
code.  Attached is the patch which incorporates the previous one and
make the following amendments:
1. find_ferry will not return ferries owned by someone else (doh!)
2. once a unit found a ferry, it will not ask for more, because
3. ferries are more faithful, they will go towards the passenger that
contacted them previously, unless they are carrying someone right now.

The TODOs outlined in the previous email are still TODOs...

G.
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.26
diff -u -r1.26 aidata.c
--- ai/aidata.c 25 May 2004 15:35:32 -0000      1.26
+++ ai/aidata.c 31 May 2004 19:03:09 -0000
@@ -401,15 +401,16 @@
 **************************************************************************/
 void ai_set_ferry(struct unit *punit, struct unit *ferry)
 {
-  if (!ferry && punit->ai.ferryboat != FERRY_WANTED) {
+  /* First delete unit from the list of passengers and release it's ferry */
+  ai_clear_ferry(punit);
+
+  if (!ferry) {
     struct ai_data *ai = ai_data_get(unit_owner(punit));
 
-    UNIT_LOG(LOG_DEBUG, punit, "want a boat.");
+    UNIT_LOG(LOG_DEBUG, punit, "wants a boat.");
     ai->stats.passengers++;
     punit->ai.ferryboat = FERRY_WANTED;
-  } else if (ferry) {
-    /* Make sure we delete punit from the list of potential passengers */
-    ai_clear_ferry(punit);
+  } else {
     punit->ai.ferryboat = ferry->id;
   }
 }
@@ -428,8 +429,11 @@
     struct unit *ferry = find_unit_by_id(punit->ai.ferryboat);
     
     if (ferry && ferry->ai.passenger == punit->id) {
+      struct ai_data *ai = ai_data_get(unit_owner(punit));
+
       /* punit doesn't want us anymore */
-      ferry->ai.passenger = FERRY_NONE;
+      ferry->ai.passenger = FERRY_AVAILABLE;
+      ai->stats.available_boats++;
     }
   }
 
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.107
diff -u -r1.107 aitools.c
--- ai/aitools.c        25 May 2004 15:47:09 -0000      1.107
+++ ai/aitools.c        31 May 2004 19:03:09 -0000
@@ -305,6 +305,7 @@
       
       unit_list_iterate(ptile->units, aunit) {
         if (is_ground_units_transport(aunit)
+           && aunit->owner == punit->owner
             && (aunit->ai.passenger == FERRY_AVAILABLE
                 || aunit->ai.passenger == punit->id)) {
           /* Turns for the unit to get to rendezvous pnt */
@@ -379,7 +380,7 @@
     ferryboat = find_unit_by_id(boatid);
 
     if (!ferryboat) {
-      UNIT_LOG(LOGLEVEL_GOTHERE, punit, "No boat found.");
+      UNIT_LOG(LOGLEVEL_GOTHERE, punit, "No boat found, requesting one.");
       if (is_ocean_near_tile(punit->x, punit->y)) {
         ai_set_ferry(punit, NULL);
       }
@@ -418,8 +419,8 @@
       /* Didn't get to the boat */
       if (is_ocean_near_tile(punit->x, punit->y)) {
         /* At least got to the coast, wave to the boats! */
-        UNIT_LOG(LOGLEVEL_GOTHERE, punit, "asking a boat to come nearer");
-        ai_set_ferry(punit, NULL);
+        UNIT_LOG(LOGLEVEL_GOTHERE, punit, 
+                "waiting for the boat to come nearer");
       }
       return FALSE;
     }
@@ -430,8 +431,9 @@
       int beach_x, beach_y;     /* Destination for the boat */
       struct tile *dest_tile = map_get_tile(dest_x, dest_y);
 
-      UNIT_LOG(LOGLEVEL_GOTHERE, punit, "got boat[%d], going (%d,%d)",
-               ferryboat->id, dest_x, dest_y);
+      UNIT_LOG(LOGLEVEL_GOTHERE, punit, 
+              "got boat[%d](moves left: %d), going (%d,%d)",
+               ferryboat->id, ferryboat->moves_left, dest_x, dest_y);
       handle_unit_load(pplayer, punit->id, ferryboat->id);
       ai_set_passenger(ferryboat, punit);
 
@@ -453,7 +455,6 @@
         beach_y = dest_y;
       }
 
-      UNIT_LOG(LOGLEVEL_GOTHERE, punit, "All aboard!");
       set_goto_dest(ferryboat, beach_x, beach_y);
       set_goto_dest(punit, dest_x, dest_y);
       /* Grab bodyguard */
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.316
diff -u -r1.316 aiunit.c
--- ai/aiunit.c 23 May 2004 02:05:37 -0000      1.316
+++ ai/aiunit.c 31 May 2004 19:03:09 -0000
@@ -2273,9 +2273,9 @@
   UNIT_LOG(LOGLEVEL_FERRY, punit, "Ferryboat is looking for cargo.");
 
   pft_fill_unit_overlap_param(&parameter, punit);
-  /* We are looking for our units, no need to look into the unknown */
-  parameter.get_TB = no_fights_or_unknown;
-  parameter.omniscience = FALSE;
+  /* If we have omniscience, we use it, since paths to some places
+   * might be "blocked" by unknown.  We don't want to fight though */
+  parameter.get_TB = no_fights;
   
   map = pf_create_map(&parameter);
   while (pf_next(map)) {
@@ -2285,7 +2285,8 @@
     
     unit_list_iterate(map_get_tile(pos.x, pos.y)->units, aunit) {
       if (punit->owner == aunit->owner 
-         && aunit->ai.ferryboat == FERRY_WANTED) {
+         && (aunit->ai.ferryboat == FERRY_WANTED
+             || aunit->ai.ferryboat == punit->id)) {
         UNIT_LOG(LOGLEVEL_FERRY, punit, 
                  "Found a potential cargo %s[%d](%d,%d), going there",
                  unit_type(aunit)->name, aunit->id, aunit->x, aunit->y);
@@ -2415,6 +2416,7 @@
 static void ai_manage_ferryboat(struct player *pplayer, struct unit *punit)
 {
   struct city *pcity;
+  int psngr_id = punit->ai.passenger;
 
   CHECK_UNIT(punit);
 
@@ -2446,7 +2448,7 @@
       if (!psngr 
          || real_map_distance(punit->x, punit->y, psngr->x, psngr->y) > 1) {
        UNIT_LOG(LOGLEVEL_FERRY, punit, 
-                "lost passenger-in-charge[%d], resetting",
+                "recorded passenger[%d] is not on board, checking for others",
                 punit->ai.passenger);
        punit->ai.passenger = 0;
       }
@@ -2527,6 +2529,24 @@
   handle_unit_activity_request(punit, ACTIVITY_IDLE);
   CHECK_UNIT(punit);
 
+  /* Were we promised to someone who still needs us? */
+  if (psngr_id > 0) {
+    struct unit *psngr = find_unit_by_id(psngr_id);
+
+    if (is_ocean_near_tile(psngr->x, psngr->y) 
+       && (psngr->ai.ferryboat == FERRY_WANTED
+           || psngr->ai.ferryboat == punit->id)) {
+
+      set_goto_dest(punit, psngr->x, psngr->y);
+      UNIT_LOG(LOGLEVEL_FERRY, punit, 
+              "recorded passenger[%d] needs us, go there", psngr_id);
+      ai_set_passenger(punit, psngr);
+      ai_set_ferry(psngr, punit);
+      ai_unit_goto(punit, goto_dest_x(punit), goto_dest_y(punit));
+      return;  
+    }
+  }
+
   /* Try to find passengers */
   if (ai_ferry_findcargo(punit)) {
     ai_unit_goto(punit, goto_dest_x(punit), goto_dest_y(punit));
Index: common/aicore/pf_tools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.c,v
retrieving revision 1.14
diff -u -r1.14 pf_tools.c
--- common/aicore/pf_tools.c    19 May 2004 00:49:31 -0000      1.14
+++ common/aicore/pf_tools.c    31 May 2004 19:03:09 -0000
@@ -379,6 +379,22 @@
   return TB_NORMAL;
 }
 
+/********************************************************************** 
+  PF callback to prohibit attacking anyone.
+***********************************************************************/
+enum tile_behavior no_fights(int x, int y, enum known_type known,
+                            struct pf_parameter *param)
+{
+  struct tile *ptile = map_get_tile(x, y);
+
+  if (is_non_allied_unit_tile(ptile, param->owner)
+      || is_non_allied_city_tile(ptile, param->owner)) {
+    /* Can't attack */
+    return TB_IGNORE;
+  }
+  return TB_NORMAL;
+}
+
 
 /* =====================  Postion Dangerous Callbacks ================ */
 
@@ -538,8 +554,6 @@
   parameter->unit_flags = unit_type(punit)->flags;
 
   parameter->omniscience = !ai_handicap(unit_owner(punit), H_MAP);
-
-
 }
 
 /**********************************************************************
Index: common/aicore/pf_tools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/pf_tools.h,v
retrieving revision 1.6
diff -u -r1.6 pf_tools.h
--- common/aicore/pf_tools.h    28 Jan 2004 21:36:48 -0000      1.6
+++ common/aicore/pf_tools.h    31 May 2004 19:03:09 -0000
@@ -26,6 +26,8 @@
 enum tile_behavior no_fights_or_unknown(int x, int y, 
                                         enum known_type known,
                                         struct pf_parameter *param);
+enum tile_behavior no_fights(int x, int y, enum known_type known,
+                            struct pf_parameter *param);
 
 #define pf_iterator(map, position) {                       \
   struct pf_position position;                             \

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