Results 1 to 20 of 20

Thread: [Tut] Loops

  1. #1
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default [Tut] Loops

    This tutorial will guide you through using loops in Scar(pascal). I will provide examples as well as descriptions for the following types of loops: for..to..do, while..do, repeat..until.

    You should already know about variables, begin..end nests, as well as basic Scar(pascal) syntax.

    for..to..do

    In my opinion, the for..do..to loop is the most useful of the three I will be covering in this tutorial. The following is an example of a basic for..to..do loop.
    SCAR Code:
    program for_to_do;

    procedure for_to_do_practice;
    var
      i: Integer;
    begin
      for i := 0 to 4 do
        Writeln(IntToStr(i));
    end;

    begin
      for_to_do_practice;
    end.
    This procedure would output:
    SCAR Code:
    0
    1
    2
    3
    4
    All a for..to..do loop does is takes the value set to the variable between the "for..to" which, in this case is "i := 0", and repeats the loop, increasing the value of "i" by one each time, until "i" is equal to the value set between the "to..do" which, in this case is "4". So, as you can see, the preceding example looped through 5 times.
    (NOTE: You must set a variable between "for..to" for the loop to count with. It doesn't need to equal "0", but you must change the value between "to..do" accordingly.)

    Now, if I wanted to execute more that one line during my for..to..do loop, I would have to add a begin..end nest(which you should already know about, if not please resort to a more basic tutorial for now).
    Example:
    SCAR Code:
    program for_to_do;

    procedure for_to_do_practice;
    var
      i: Integer;
    begin
      for i := 0 to 4 do
      begin
        if i <= 2 then // if "i" is less than or equal to 2 then
          Writeln(IntToStr(i))  // do this
        else  //otherwise
          Writeln('i is greater than 2.'); // do this.
      end;
    end;

    begin
      for_to_do_practice;
    end.
    In this case the procedure would output:
    SCAR Code:
    0
    1
    2
    i is greater than 2.
    i is greater than 2.

    While on this topic I will also talk briefly about for..downto..do loops. They are basically the same thing as a for..to..do loop, just counting down, instead of up.
    Example:
    SCAR Code:
    program for_to_do;

    procedure for_to_do_practice;
    var
      i: Integer;
    begin
      for i := 4 downto 0 do
        Writeln(IntToStr(i));
    end;

    begin
      for_to_do_practice;
    end.
    This procedure would output:
    SCAR Code:
    4
    3
    2
    1
    0
    Simple, yet effective.
    If you work with arrays at all you will find these loops to be extremely useful.


    while..do
    The syntax for a while..do loop is:
    SCAR Code:
    while Statement = True do
      WhateverYouWantTheLoopToDo;
    So, with a while..do loop, as long as the statement between while..do remains true, the loop will continue to repeat.

    Example:
    SCAR Code:
    program while_do_loops;

    procedure while_do_practice;
    var
      i: Integer;
    begin
      i := 0; //set the value of "i" equal to "0"
      while i <= 4 do //while "i" is less than or equal to 4 do the following..
      begin
        Writeln(IntToStr(i));
        Inc(i); //Increases the value of "i" by 1
      end;
      Writeln('The loop is over because i = '+IntToStr(i)+';');
    end;

    begin
      while_do_practice;
    end.
    The preceding procedure would output:
    SCAR Code:
    0
    1
    2
    3
    4
    The loop is over because i = 5;
    As you can see, a while..do loop checks the statement before it executes the actual loop. Therefor, if the statement returns false, it will skip over the loop to the next part of the procedure.

    Example:
    SCAR Code:
    program while_do_loops;

    procedure while_do_practice;
    var
      i: Integer;
    begin
      i := 5; //set the value of "i" equal to "5"
      while i <= 4 do //while "i" is less than or equal to 4 do the following..
      begin
        Writeln(IntToStr(i));
        Inc(i); //Increases the value of "i" by 1
      end;
      Writeln('The loop is over because i = '+IntToStr(i)+';');
    end;

    begin
      while_do_practice;
    end.
    In this case, because "i" is greater than 4, the compiler will skip over the loop it self, and so the output would be:
    SCAR Code:
    The loop is over because i = 5;


    repeat..until

    The repeat..until loop is pretty self-explanatory. The syntax goes as follows:
    SCAR Code:
    repeat
      Loop;
    until(Statement = True);

    As you can see, unlike the while..do loop, the repeat..until loop checks the statement after the loop, therefor, the loop is guaranteed to run through at least once.

    Example:
    SCAR Code:
    program repeat_until_loops;

    procedure repeat_until_practice;
    var
      i: Integer;
    begin
      i := 0;
      repeat
        Writeln(IntToStr(i));
        Inc(i);
      until(i >= 5);
      Writeln('The loop is over because i = '+IntToStr(i)+';');
    end;

    begin
      repeat_until_practice;
    end.
    This procedure would output:
    SCAR Code:
    0
    1
    2
    3
    4
    The loop is over because i = 5;
    Now, keep in mind that the loop will execute at least once because it checks the statement at the end.

    Example:
    SCAR Code:
    program repeat_until_loops;

    procedure repeat_until_practice;
    var
      i: Integer;
    begin
      i := 5;
      repeat
        Writeln(IntToStr(i));
        Inc(i);
      until(i >= 5);
      Writeln('The loop is over because i = '+IntToStr(i)+';');
    end;

    begin
      repeat_until_practice;
    end.
    Would output:
    SCAR Code:
    5
    The loop is over because i = 6;
    As you can see, even though "i" was already equal to 5, the compiler still executed the loop once because it didn't check the statement until after the loop.


    BEWARE OF INFINITE LOOPS!
    An "Infinite Loop" is a loop that has a possibility of never ending.

    Example:
    SCAR Code:
    procedure Infinite_Loop_Practice;
    begin
      repeat
        Writeln('This loop may never end!');
      until(ThisFunction);
    end;
    The above repeat..until loop would continue to repeat until "ThisFunction" returned true. Therefor, if something went wrong and "ThisFunction" never returned true, the loop would just continue to repeat until it was stopped manually. This can become incredibly dangerous especially if you're planning to script for RuneScape, as an Infinite loop may lead to a ban :/. So be careful!

    BREAKING LOOPS
    You may be wondering how you can prevent an Infinite loop.Your looking for a what is known as a "failsafe". for..to..do loop's are good for avoiding infinite loops because they have a sort of "built in" failsafe. Since, as you should know by this point, they have a set amount of times they can loop through before ending.
    However, if you would prefer not to use a for..to..do loop there are a couple ways to implement your own failsafes into your loops.

    Counting FailSafe

    One method you could use would be counting. By "counting" I meen to increase the value of a variable to keep track of loop number. (Count each loop). This method basically just sets a limit to the containing loop.
    Your going to need to know before hand a maximum amount of times you want the program to loop through before it is "too many" and you want it to stop. (or have it set to a variable and have a value passed to it during run time.) The reason I recommend a for..to..do loop is because it just saves the script writer (you) from having to increment the "counting variable" your self.
    Also, make sure you understand this simple procedure:
    SCAR Code:
    procedure Inc(x: Integer);
    All it does is increase "x" by 1.

    Example of a Counting failsafe:
    SCAR Code:
    procedure Counting_failsafe_practice;
    var
      Counter: Integer; //It doesn't have to be named "counter" I just chose that for readability.
    begin
      Counter := 0; // Be sure to set the starting value of your "counting variable" BEFORE the loop, so it doesn't reset every time your loop goes through.
      while(not (ThisFunction)) do //while ThisFunction = false do..
      begin
        Inc(Counter); // Increase the value of "Counter" by 1.
        if Counter >= 4 then // if the value of "Counter" is greater than or equal to 4 then...
          Break; //By calling this the program will now quit this loop.
      end;
    end;
    As you can see, the above procedure will continue looping through until either ThisFunction returns true, or the value of "Counter" is 5 or greater. Which we then exit the loop by calling "Break;".

    Timing FailSafe

    Another type of custom failsafe you could add to your loop would be a "Timer". You can find a lot of other functions to go along with this type of failsafe in Timing.Scar. Once you get the hang of using timers you will be able to experiment with using them different ways, but for now I will just show you a basic way to do it.
    First, I suggest looking over/familiarizing yourself with these two functions from Timing.Scar:
    SCAR Code:
    {*******************************************************************************
    procedure MarkTime(var TimeMarker: Integer);
    By: Stupid3ooo
    Description: Sets TimeMarker to current system time
    *******************************************************************************}


    procedure MarkTime(var TimeMarker: Integer);
    begin
      TimeMarker := GetSystemTime;
    end;

    {*******************************************************************************
    function TimeFromMark(TimeMarker: Integer): Integer;
    By: Stupid3ooo
    Description: returns Milliseconds since MarkTime was set
    *******************************************************************************}


    function TimeFromMark(TimeMarker: Integer): Integer;
    begin
      Result := GetSystemTime - TimeMarker;
    end;
    Example of a "Timing" failsafe:
    SCAR Code:
    procedure Timing_Failsafe_Practice;
    var
      Timer: Integer; // Declare our variable to track time with.
    begin
      MarkTime(Timer); // Sets a marker for the current time and stores it in "Timer".
      repeat
        Wait(100);
      until((ThisFunction) or (TimeFromMark(Timer) >= 5000));
    end;
    Hopefully, from reading the above code you can figure out that the loop will keep going until either "ThisFunction" returns true, or our "Timer" has been going for greater than or equal to 5 seconds. Remember that the timing is measured in milliseconds so 1000 = 1 second etc.

    Labels
    Labels are used to skip from one part of code to another during runtime.
    One thing you NEED to know is: Labels can NOT be used to break out of a loop! You will get an error.
    There are three steps to using Labels that will be shown in the example below.

    Example of using Labels:
    SCAR Code:
    procedure LabelDemo;
    label Marker; //Step 1: Declare our "Marker" (to mark our "jump to" point in code)
    begin
      DoThis;
      if ThisIsTrue then
        goto Marker;  //Step 2: the "goto" command tells the compiler to skip to where it finds the "Marker".
      ThisFunction;
      Marker: //Step 3: Set "Marker" (this is where the script will skip to. Notice the ':' When setting a "marker" for a label you will need to follow it with a colon ( : ) instead of a semicolon ( ; )
    end;
    In this case if the function "ThisIsTrue" returns true, it will skip over "ThisFunction" and continue to run after "Marker".

    USEFUL FUNCTIONS WITH LOOPS

    Continue;
    'Continue;' can be a very useful little function when working with loops. By calling 'Continue;' the script will then skip to the end of the current loop. Many people seem to think it skips to the beginning, but that is false.

    For example:
    Simba Code:
    var
      i: Integer;
    begin
      i := 0;
      repeat
        Inc(i);
        Writeln(IntToStr(i));
        if i = 1 then
          Continue;
        Writeln('i must not be 1');
      until(i = 1);
    end.
    Would output:
    Progress Report:
    Compiled succesfully in 593 ms.
    1
    Successfully executed.


    Another example would be:
    Simba Code:
    for i := 0 to High(Objects) do
    begin
      if FindObject(Objects[i], ...) then //Just for an example
        Continue
      else begin
        WalkHere;
        DoThis;
      end;
      Wait(3000);
      Writeln('not found');
    end;
    In the above example if 'Continue;' is called, it will skip:
    Simba Code:
    else begin
        WalkHere;
        DoThis;
      end;
      Wait(3000);
      Writeln('not found');

    And that concludes my tutorial on loops. For now, anyways.
    If anyone feels I left anything out or would like me to add something please don't hesitate to say so.

    Thanks for reading, hope you learned something
    Last edited by NCDS; 01-12-2011 at 02:09 AM. Reason: Update!

  2. #2
    Join Date
    Oct 2006
    Location
    ithurtsithurtsithurtsithurts
    Posts
    2,930
    Mentioned
    7 Post(s)
    Quoted
    135 Post(s)

    Default

    Nice tut. Glad to see you covering the differences between while..do and repeat..until.

  3. #3
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Thanks Senrath. It's the first tut I ever wrote really. I wasn't sure if I was explaining things simple enough or not.

  4. #4
    Join Date
    Nov 2007
    Location
    46696E6C616E64
    Posts
    3,069
    Mentioned
    44 Post(s)
    Quoted
    302 Post(s)

    Default

    Cool tut, even thought i knew almost all it except the last part about repeat..until();
    There used to be something meaningful here.

  5. #5
    Join Date
    May 2007
    Location
    Ohio
    Posts
    2,296
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    why are you confusing them?
    SCAR Code:
    begin
      ...._practice;
    end.
    please

  6. #6
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Quote Originally Posted by Timer View Post
    why are you confusing them?
    SCAR Code:
    begin
      ...._practice;
    end.
    please
    What...?

  7. #7
    Join Date
    Oct 2006
    Location
    ithurtsithurtsithurtsithurts
    Posts
    2,930
    Mentioned
    7 Post(s)
    Quoted
    135 Post(s)

    Default

    Quote Originally Posted by NCDS View Post
    What...?
    Oh, I see. You messed up on the main loop. You have end; instead of end.

  8. #8
    Join Date
    Dec 2006
    Location
    Houston, TX USA
    Posts
    4,791
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    What about labels and functions/proc that call themselves?

  9. #9
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Quote Originally Posted by senrath View Post
    Oh, I see. You messed up on the main loop. You have end; instead of end.
    >.< Fixed. Thanks for pointing that out.

    Quote Originally Posted by IceFire908 View Post
    What about labels and functions/proc that call themselves?
    The thought never even crossed my mind to add those. I can though

  10. #10
    Join Date
    Feb 2007
    Location
    Alberta,Canada
    Posts
    2,358
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    you should also address the issue of infinite loops and how to break loops via timers, etc. (t := getSystemTime stuff).
    “Ignorance, the root and the stem of every evil.”

  11. #11
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Quote Originally Posted by Blumblebee View Post
    you should also address the issue of infinite loops and how to break loops via timers, etc. (t := getSystemTime stuff).
    I did mean to add that. I wrote this at like 2 or 3a.m. last night?

    I'll add updates later on tonight.

  12. #12
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Updated.

    Added a big section on breaking loops.

    Will add a section on labels soon. (either a little later tonight or tomorrow.)

    I'm still debating whether or not to add a part on a recursive method as the way it's used (sorting techniques) seems a bit advanced for a beginners tut. I may still do it though.

    Take a look through, see if I missed anything this time. I should probably stop waiting till so late at night to do these..


    Edit: Added labels.
    Last edited by NCDS; 01-21-2010 at 02:44 AM.

  13. #13
    Join Date
    Mar 2006
    Location
    Behind you
    Posts
    3,193
    Mentioned
    61 Post(s)
    Quoted
    63 Post(s)

    Default

    Exit; might be a good peice to add in there also.

    "Sometimes User's don't need the Answer spelled out with Code. Sometimes all they need is guidance and explanation of the logic to get where they are going."

  14. #14
    Join Date
    Jan 2010
    Posts
    5,227
    Mentioned
    6 Post(s)
    Quoted
    60 Post(s)

    Default

    ^ I believe Exit exits the function, not the loop.

    Pascal Code:
    if(not(LoggedIn))then
      Exit;

    No loop there.

  15. #15
    Join Date
    Mar 2006
    Location
    Behind you
    Posts
    3,193
    Mentioned
    61 Post(s)
    Quoted
    63 Post(s)

    Default

    Quote Originally Posted by i luffs yeww View Post
    ^ I believe Exit exits the function, not the loop.

    Pascal Code:
    if(not(LoggedIn))then
      Exit;

    No loop there.
    True, but i use in it my function loops.

    SCAR Code:
    Function Fslime(var x,y:integer):boolean;                          
    var                                                                
     t:integer;                                                        
    begin                                                              
    t:=0;                                                              
    repeat                                                              
      wait(200+random(100));                                            
      inc(t);                                                          
      if findcolortolerance(x,y,14089436,217,155,241,194,5) then        
      begin                                                            
        result:=true;                                                  
        writeln('Found Slime');                                        
        Mmouse(x,y,5,5);                                                
        exit;                                                          
      end else                                                          
      writeln('failed to find slime ' + inttostr(t) + ' Times.');      
    until (t>10)                                                        
    end;

    It's not really covered in most other tut's either.

    "Sometimes User's don't need the Answer spelled out with Code. Sometimes all they need is guidance and explanation of the logic to get where they are going."

  16. #16
    Join Date
    Mar 2008
    Location
    In a cave
    Posts
    345
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Care to add a little paragraph about Continue; as there have been a few threads about it lately in the Help section and it applies to all loops.
    A simple example wouldn't harm either
    Simba Code:
    repeat
      Inc(i);
      if i = 3 then Continue;
      Writeln(i);
    until i >= 5;

    In addition to that I think you should add recursion here too. It's not that hard to understand at all if there is a simple example. I guess an alpha-beta algorithm would be a bit too much for this section, but a very basic overview of recursion would be nice
    A Chinese wiseman once said: "Shu ciu!", it was considered very smart, but now people know it means: "Something stinks here!"
    FalBuggySmelter v.1.31
    [Updated on the 1st of March 2010]
    RimmBugger BETA V1.8

  17. #17
    Join Date
    Jan 2009
    Location
    Belgium
    Posts
    175
    Mentioned
    0 Post(s)
    Quoted
    14 Post(s)

    Default

    Damn nice, i learned a new thing ^^ i noticed Labels could be very handy
    btw u might add: continue; break; exit; to the tutorial since they are used in a loop most of the time.

    rep+

  18. #18
    Join Date
    Oct 2007
    Location
    #srl
    Posts
    6,102
    Mentioned
    39 Post(s)
    Quoted
    62 Post(s)

    Default

    Quote Originally Posted by Yush Dragon View Post
    Damn nice, i learned a new thing ^^ i noticed Labels could be very handy
    btw u might add: continue; break; exit; to the tutorial since they are used in a loop most of the time.

    rep+
    'Exit;' exits the function, I believe 'Break;' is covered, and I will add a little description for 'Continue' in just a minute as requested by Bugger as well.

    Edit: Added the 'Continue' bit.

  19. #19
    Join Date
    Jun 2011
    Posts
    4
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Thank you for sharing the post.

  20. #20
    Join Date
    Oct 2008
    Posts
    196
    Mentioned
    1 Post(s)
    Quoted
    20 Post(s)

    Default

    thanks a lot. I think labels are going to be a crucial part in my upcoming script

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •