Complete.Org: Mailing Lists: Archives: freeciv-ai: June 2004:
[freeciv-ai] (PR#9033) Infinite loop in ai_manage_ferryboat()
Home

[freeciv-ai] (PR#9033) Infinite loop in ai_manage_ferryboat()

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: use_less@xxxxxxxxxxx
Subject: [freeciv-ai] (PR#9033) Infinite loop in ai_manage_ferryboat()
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxxx>
Date: Sun, 20 Jun 2004 05:29:02 -0700
Reply-to: rt@xxxxxxxxxxx

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

> [use_less - Sat Jun 19 21:26:27 2004]:
> 
> In ai_manage_ferryboat() in aiunit.c, there is a possibility for an
> infinite loop.
> 
> If the boss of a ferryboat is off the boat, has no more moves left, and
> not released control of the ferryboat, and the ferryboat has other
> passengers, the ferry will loop continuously waiting for the boss to
> move onto the boat.
> 
> This patch makes the ferryboat abandon its previous boss if it has  other
> passengers on the boat.  This seems to fix the infinite loop, but may
> have other consequences.
> 

The bug is now probably impossible to reproduce: before it was due to
incorrectly waiting for the passenger that just got off the boat but
forgot to release it.  Now this forgetfullness is cured in a latest commit.

However, the possibility of a loop is still there.  So I updated the
patch and will commit it today.

G.

? ai/aisettler.c
? ai/aisettler.h
? data/flags/Makefile
? data/flags/Makefile.in
Index: ai/aiferry.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiferry.c,v
retrieving revision 1.1
diff -u -r1.1 aiferry.c
--- ai/aiferry.c        20 Jun 2004 07:41:14 -0000      1.1
+++ ai/aiferry.c        20 Jun 2004 12:25:27 -0000
@@ -715,7 +715,7 @@
   }
 
   /* Check if we are an empty barbarian boat and so not needed */
-  if (is_barbarian(pplayer) && !punit->occupy) {
+  if (is_barbarian(pplayer) && get_transporter_occupancy(punit) == 0) {
     wipe_unit(punit);
     return;
   }
@@ -728,9 +728,7 @@
       struct unit *psngr = find_unit_by_id(punit->ai.passenger);
       
       /* If the passenger-in-charge is adjacent, we should wait for it to 
-       * board.  We will pass control to it later.
-       * FIXME: A possible side-effect: a boat will linger near a passenger 
-       * which already landed. */
+       * board.  We will pass control to it later. */
       if (!psngr 
          || real_map_distance(punit->x, punit->y, psngr->x, psngr->y) > 1) {
        UNIT_LOG(LOGLEVEL_FERRY, punit, 
@@ -787,16 +785,21 @@
       if (!find_unit_by_id(id) || punit->moves_left <= 0) {
         return;
       }
-      if (find_unit_by_id(bossid) 
-         && same_pos(punit->x, punit->y, boss->x, boss->y)) {
-       /* The boss decided to stay put on the ferry. We aren't moving. */
-       return;
+      if (find_unit_by_id(bossid)) {
+       if (same_pos(punit->x, punit->y, boss->x, boss->y)) {
+         /* The boss decided to stay put on the ferry. We aren't moving. */
+         return;
+       } else if (get_transporter_occupancy(punit) != 0) {
+         /* The boss isn't on the ferry, and we have other passengers?
+          * Forget about him. */
+         punit->ai.passenger = 0;
+       }
       }
     } else {
       /* Cannot select a passenger-in-charge */
       break;
     }
-  } while (punit->occupy != 0);
+  } while (get_transporter_occupancy(punit) != 0);
 
   /* Not carrying anyone, even the ferryman */
 

[Prev in Thread] Current Thread [Next in Thread]
  • [freeciv-ai] (PR#9033) Infinite loop in ai_manage_ferryboat(), Gregory Berkolaiko <=