Author Topic: 'for' statement and flow control  (Read 244 times)

Legacy_WhiteTiger

  • Hero Member
  • *****
  • Posts: 889
  • Karma: +0/-0
'for' statement and flow control
« on: December 24, 2014, 07:55:33 pm »


               

When do we use 'for' statement scripting?



               
               

               
            

Legacy_Kantr

  • Newbie
  • *
  • Posts: 6
  • Karma: +0/-0
'for' statement and flow control
« Reply #1 on: December 24, 2014, 08:12:02 pm »


               

to keep the statement going until it becomes false. Stuff like sustained effects I guess



               
               

               
            

Legacy_Tarot Redhand

  • Hero Member
  • *****
  • Posts: 4165
  • Karma: +0/-0
'for' statement and flow control
« Reply #2 on: December 24, 2014, 08:23:33 pm »


               

When you need to repeat one or more statements usually for a set number of times is the short answer. The longer answer is whenever you need to. Whole chapters could be written to answer this.


 


TR



               
               

               
            

Legacy_WhiteTiger

  • Hero Member
  • *****
  • Posts: 889
  • Karma: +0/-0
'for' statement and flow control
« Reply #3 on: December 24, 2014, 08:37:54 pm »


               

Like 'while'?



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
'for' statement and flow control
« Reply #4 on: December 24, 2014, 09:12:30 pm »


               

For loops are generally used when you have a known (or fixed) number of iterations to do. For example if you know you can effect casterlevel creatures with an effect you could use a for loop from 1 to casterlevel.  While is generally used when you don't know the number of iterations (there are lots of examples in the lexicon of using while to say look at each item in inventory etc) or when there are multiple conditions. These are not fast rules of course. You can pretty much make a while loop do anything a for loop can do and vice versa.  I believe there is a tutorial on loops in the lexicon.


               
               

               
            

Legacy_Tarot Redhand

  • Hero Member
  • *****
  • Posts: 4165
  • Karma: +0/-0
'for' statement and flow control
« Reply #5 on: December 24, 2014, 11:01:31 pm »


               

As the scripting language for NwN is based on the C family (C, C++, C#, etc.) of programming languages, it is worth pointing out that in this family the for loop is regarded as just a specialised form of the while loop.


 


TR



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
'for' statement and flow control
« Reply #6 on: December 24, 2014, 11:47:22 pm »


               "for" is shorthand for a "while" loop on a counter.


It's a matter of preference. Personally, I tend to use "while" rather than "for", as it's clear, simple and easy to remember (especially if you use many different languages), but that's just me.
               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
'for' statement and flow control
« Reply #7 on: December 25, 2014, 01:49:16 am »


               

Heh, I thought I hedged enough with "generally" and "not fast rules" that what I was saying was more helpful than controversial, apparently I was wrong '<img'>


 


Fwiw, "for" is more than just shorthand for a "while" loop with a counter. Consider the use of the continue statement. Also "for" loops (in other languages than NWNscript) do not require counters.


 


Edit: Not trying to turn this into argument though. Happy Holidays fellow NWNers!



               
               

               
            

Legacy_ShadowM

  • Hero Member
  • *****
  • Posts: 1373
  • Karma: +0/-0
'for' statement and flow control
« Reply #8 on: December 25, 2014, 08:54:27 am »


               

(For) is good for running the same action over a set number of times. For example in my skinning system. I have a skill check for each meat you can get off a creature. The number meats being based off the size of the creature and with ( for loop) I can run it really easy.



               
               

               
            

Legacy_Tarot Redhand

  • Hero Member
  • *****
  • Posts: 4165
  • Karma: +0/-0
'for' statement and flow control
« Reply #9 on: December 25, 2014, 11:18:30 am »


               

Examples guys? I would but I've got to wrestle a dead ostrich (well that's what it looks like not the turkey it actually is) into an oven (that looks) too small for it.


 


TR



               
               

               
            

Legacy_Squatting Monk

  • Hero Member
  • *****
  • Posts: 776
  • Karma: +0/-0
'for' statement and flow control
« Reply #10 on: December 25, 2014, 07:45:54 pm »


               Here's some examples of each:
// Check to see if the player has at least five goblin ears
int StartingConditional()
{
    int nCount;
    object oPC = GetPCSpeaker();
    object oItem = GetFirstItemInInventory(oPC);
    
    while (GetIsObjectValid(oItem))
    {
        if (GetTag(oItem) == "goblin_ear")
            nCount++;
        
        oItem = GetNextItemInInventory(oPC);
    }
    
    return nCount >= 5;
}
 
// Create five goblin ears in the player's inventory
void main()
{
    int i;
    object oPC = GetPCSpeaker();
    
    for (i = 0; i < 5; i++)
    {
        CreateItemOnObject("goblin_ear", oPC);
    }
}

               
               

               
            

Legacy_WhiteTiger

  • Hero Member
  • *****
  • Posts: 889
  • Karma: +0/-0
'for' statement and flow control
« Reply #11 on: December 26, 2014, 09:48:14 pm »


               

That's a good stuff, thanks folks



               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
'for' statement and flow control
« Reply #12 on: December 30, 2014, 03:24:05 am »


               I kinda wish nwnscript had a real implimentation of a foreach statement.

I think it might be achieveable with nwnx - but it would be very hacky.

Eg:
Create a list in memory
add object references to it
and each time you call a method like NWNX_GetNext("ContainerName") - it increments the index of the current selection - until it reaches the end of the list.


for(NWNX_GetNext("ContainerName") != FALSE){
    object o = NWNX_GetCurrentObject("ContainerName");  
    //Do something
}
Of course - this could in theory be done in nwscript too- with use of Set/GetLocalObject
Just do a wrapper method around them, and make it return TRUE if the next item in the list is valid, FALSE if not - and then on a TRUE condition, set another LocalVar to be the actual object reference.

Its alot of work to get a simple - ForEach statement working.
It might be easier to use

for(i=0;i<=MAX_SIZE;i++)
{

}
The obvious benefits of a foreach is that it doesnt require you to know the amount of items in the list
With the SetLocal/GetLocal approach - you are going to sorta need to know that information :
If you are just checking to see if an object is not OBJECT_INVALID - then you will run into issues when object 5 out of 15 (a creature), dies and gets cleaned up by his body disappearing.
Object 5 becomes OBJECT_INVALID, and it would break the loop - preventing progression to objects 6-15 etc
               
               

               
            

Legacy_Tarot Redhand

  • Hero Member
  • *****
  • Posts: 4165
  • Karma: +0/-0
'for' statement and flow control
« Reply #13 on: December 30, 2014, 12:26:57 pm »


               

To some extent you can have behaviour that is similar to the For Each command that you desire. The restrictions are that the things that you wish to step through must all be objects and they must all have the same, identical tag. Here is a simple example taken from my Deadly Candles submission to October's (Ravenloft) custom content challenge.


// ExtinguishAllCandles steps through all candles, extiguishing those that are
// lit and telling them they are unlit. Also empties the string "sAllLitCandles"
 
void ExtinguishAllCandles()
{
    int iCandleNum = 0;
    object oWayPoint = GetNearestObjectByTag("WP_HereBeMonsters");
    object oCandle = GetObjectByTag("TrapCandle", iCandleNum);
 
    while(GetIsObjectValid(oCandle))
    {
        if(GetLocalInt(oCandle, "bAmAlight"))
        {
            AssignCommand(oCandle, PlayAnimation(ANIMATION_PLACEABLE_DEACTIVATE));
            SetLocalInt(oCandle, "bAmAlight", FALSE);
        }
        oCandle = GetObjectByTag("TrapCandle", ++iCandleNum);
    }
    SetLocalString(oWayPoint, "sAllLitCandles", "");
}

This works because GetObjectByTag has 2 parameters and not just the 1 normally used.


 


TR



               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
'for' statement and flow control
« Reply #14 on: December 30, 2014, 11:06:19 pm »


               

Heh, I thought I hedged enough with "generally" and "not fast rules" that what I was saying was more helpful than controversial, apparently I was wrong '<img'>

 

Fwiw, "for" is more than just shorthand for a "while" loop with a counter. Consider the use of the continue statement. Also "for" loops (in other languages than NWNscript) do not require counters.

 

Edit: Not trying to turn this into argument though. Happy Holidays fellow NWNers!




First let me state that I am not wanting to turn this into an argument either.


It sounds like you are trying to say that the FOR control structure is not just a glorified while loop. That due to the assumption that it does not have a 'continue' statement as part of the control structure it is entirely different. Where both the 'continue' and the 'break' statements will work in either loop.


Try this sample code in the OnUse of a placeable.

 




 const int DO_FOREVER =1;
void main()
{
 int x;
 while (DO_FOREVER)
 {
    x++;
    if (x&1) continue;
    SpeakString( IntToString(x));
    if (x>20) break;
 }
}


To me the matter of 'For' vs. 'while'  is a matter of convention.  Both compile to pretty much the same thing, With the 'while' loop giving more control over where in the loop the continuation data gets modified.   Even with the the choice between the two has more to do with which one is easier for the writer of the script to use or any intended audience to read.    It is kind of like having a long debate on using 'i' or 'n'  in front of your integers.    


 


Just to sum this up.   The 'for' loop is nothing more then a while loop with a 'preloop statment'  and a 'endloop statement' added to the control structure. You can in fact write any 'for' loop as a while loop.   Both loops below will compile to the same thing.  



for ('preloop statment'; 'conditional statement';'endloop statement')
{

   SpeakString.....bla bla bla. 

}


'preloop statment';
while ('conditional statement')
{
   
   SpeakString.....bla bla bla.

  'endloop statement'; 
}