Avoiding Nested Ifs In Loops

A few days ago we looked at cases where we could remove nested if statements from some functions. while loops often have nested if statements; code like the rocket damage code loops through a collection of entities and then tests each one to see if it can be damaged. The previous post hinged on returning from a function when an if statement failed. In a loop we can’t return from the function – that would skip the rest of the entities!

Instead we are going to use the lesser known continue keyword. What it does is skip the rest of the current loop, and takes you back to the top of the next one. Imagine we start with the following, simplified version of the T_RadiusDamage function:

   head = findradius(origin, 120);
   while(head != world)
   {
      if(head.takedamage)
      {
         if(head != ignore)
         {
            r = random() * 20 + 90;
            T_Damage(head, r);
         }
      }
      head = head.chain;
   }

If we copied the original pattern of negating the if statements, but following them with continue instead of return we’d get:

   head = findradius(origin, 120);
   while(head != world)
   {
      if(!head.takedamage)
         continue;

      if(head == ignore)
         continue;

      r = random() * 20 + 90;
      T_Damage(head, r);
      head = head.chain;
   }

There’s a big problem with this code, it will loop infinitely most of the time! We need the head = head.chain code to run each time through the loop, not just when the tests pass. We could add it to each of the continue clauses, but that’s a bit ugly.

A better fix all round is to change the loop to use for. We can move the “head initialisation” into the first bit of the for statement, and the “next entity” code into the last bit:

   for(head = findradius(origin, 120);
       head != world;
       head = head.chain)
   {
      if(!head.takedamage)
         continue;

      if(head == ignore)
         continue;

      r = random() * 20 + 90;
      T_Damage(head, r);
   }

Now our loop is entirely contained in a single for block. In order to us the for loop, and the continue keyword, you may need to upgrade your compiler. FTEQCC supports these features, and FRIKQCC as well I think.

Advertisements

2 thoughts on “Avoiding Nested Ifs In Loops

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s