Package: crawl
Version: 1:4.0.0beta26-4
Severity: normal
Tags: patch

I was going to send this directly to upstream, but I have had some trouble with yahoogroups before, so perhaps you'll forward this instead.

Crawl 4.0.0beta26-4 from Debian GNU/Linux was caught in an infinite loop when my Troll was descending to Level 12 of the Dungeon. It consumed 99% CPU and did not make any system calls. By examining the process with GDB, I found that the loop was in this part of dungeon.cc (box_room_doors):

   while(new_doors > 0 && spot_count > 0)
   {
       spot = random2(spot_count);
       if (good_doors[spot] != 1)
           continue;

doors_placed and new_doors were both 1, spot_count was 28, and the first 28 elements of good_doors were all zero. I then changed spot_count to 0, and the game continued.

The attached patch works around the problem by making box_room_doors not try to set up more doors than possible. I think this may lead to some rooms having no doors at all, but surely that is better than wasting the whole character.

crawl (1:4.0.0beta26-4.kon.1) local; urgency=medium

  * Local version!
  * source/dungeon.cc (box_room_doors): Give up if there are not enough
    good spots, instead of falling in an infinite loop.

 -- Kalle Olavi Niemitalo <[EMAIL PROTECTED]>  Sat, 18 Jun 2005 10:07:51 +0300

--- crawl-4.0.0beta26.orig/source/dungeon.cc
+++ crawl-4.0.0beta26/source/dungeon.cc
@@ -5,7 +5,8 @@
  *
  *  Change History (most recent first):
  *
- *
+ *   <10>    18-Jun-2005 KON    box_room_doors gives up if there are not
+ *                              enough good spots.
  *   <9>     07-Aug-2001 MV     clean up of give_item; distribution of
  *                              wands, potions and scrolls
  *                              underground rivers and lakes
@@ -7538,6 +7539,14 @@
         return doors_placed;
     }
 
+    // Avoid an infinite loop if there are not enough good spots. --KON
+    j = 0;
+    for (i=0; i<spot_count; i++)
+        if (good_doors[i] == 1)
+            j++;
+    if (new_doors > j)
+        new_doors = j;
+
     while(new_doors > 0 && spot_count > 0)
     {
         spot = random2(spot_count);
-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Kernel: Linux 2.4.23-kon.astalo.1
Locale: LANG=fi_FI.UTF-8, LC_CTYPE=fi_FI.UTF-8 (charmap=UTF-8)

Versions of packages crawl depends on:
ii  libc6                       2.3.2.ds1-22 GNU C Library: Shared libraries an
ii  libgcc1                     1:3.4.3-6    GCC support library
ii  libncurses5                 5.4-3        Shared libraries for terminal hand
ii  libstdc++5                  1:3.3.5-8    The GNU Standard C++ Library v3

-- no debconf information

Attachment: pgpEZ4qWMPbPE.pgp
Description: PGP signature

Reply via email to