ifcheck question

Posted by Tzaro on Tue 11 Jul 2006 02:09 PM — 5 posts, 17,681 views.

USA #0
I'm looking for a 'shortcut' to help clean up some of my code...

In struct clan_data, I changed int Class to short Class[7]. I did this so certain orders/clans/whatever could have only certain classes join their group (up to 7 different classes), if they wanted it class-specific. This is all fine and dandy, but when updating the code, I ended up having to do checks like:

   if( victim->Class != ( clan->Class[0] || clan->Class[1] || clan->Class[3] <etc> ) )

Is there a way I could change that so it'd loop the checks like...

   if( victim->Class != clan->Class[<0 through 6>] )
   {
      <blah>
   }

Hopefully you understand what I mean... :X Thanks in advance!

-Tz
Amended on Tue 11 Jul 2006 02:14 PM by Tzaro
USA #1
You could use a for loop to do that.
for ( a=0; a < MAX_CLASSES; a++ )
{
   if( victim->Class != clan->Class[a] )
        <blah>
}

Where MAX_CLASSES would be whatever your Class[x] max would be.
Amended on Tue 11 Jul 2006 02:57 PM by Zeno
USA #2
Quote:
if( victim->Class != ( clan->Class[0] || clan->Class[1] || clan->Class[3] <etc> ) )
This is not doing at all what you think it's doing: it's doing a boolean or on the classes, and if one of them is non-zero, the overall result will be true, and that will be compared to victim->Class, which is really not what you want.

Here's a better solution:

bool IntArrayFind(int * arr, int size, int item)
{
  int i;

  // Loop over all elements, looking for 'item'
  for ( i = 0; i < size; i++ ) {
    // is this the one we're looking for?
    if ( arr[i] == item )
      return TRUE;
  }

  // not found:
  return FALSE;
}


And then, your if statement looks like this:

if ( IntArrayFind(clan->Class, NUM_CLAN_CLASSES, victim->Class) == FALSE ) {
  // do something interesting, yay
}


where you have previously defined NUM_CLAN_CLASSES to be 7.

This is a much better solution than using several if checks. And incidentally, you can reuse it whenever you need to search an array of integers.
Amended on Tue 11 Jul 2006 02:25 PM by David Haley
USA #3
hahaha... I'm a moron. Apparently, I needed some sleep...

   if( victim->Class != ( clan->Class[0] || clan->Class[1] || clan->Class[3] <etc> ) )

I used the above originally... and eventually switched it to:
   if( ( victim->Class != clan->class[0] ) &&
       ( victim->Class != clan->class[0] ) &&
       ( victim->Class != clan->class[0] ) &&
       ( victim->Class != clan->class[0] ) &&
       ( victim->Class != clan->class[0] ) &&
       ( victim->Class != clan->class[0] ) &&
       ( victim->Class != clan->class[0] ) )

I switched it because it (obviously) didn't work, but I had no idea why, and that was the only thing I could come up with that actually did what I wanted. Thanks for filling me in on the 'why' Ksilyan!

Anyway, that just seemed like quite a bit to type and figured there's probably a much better way of executing those checks. I'll give both of those a shot and figure out which one I like more. Thanks for the input Zeno and Ksilyan. Much appreciated :)
USA #4
I would suggest going with the helper function, since chances are you will need to do this in several places. Avoiding redundant code is important, and a helper function is an excellent way to recycle code. (Not to mention that this would be useful anytime you need to search an array of numbers for a number.)

Basically, whenever you find yourself typing something repetitive without thought, chances are it's something you can program in and have the program do it for you. :)