Results 1 to 11 of 11

Thread: The Scan and React Method

  1. #1
    Join Date
    Jun 2012
    Posts
    586
    Mentioned
    112 Post(s)
    Quoted
    296 Post(s)

    Default The Scan and React Method

    The Scan and React Method



    Introduction


    So, I've seen a lot of scripts from different people. These scripts use various different methods. One prominent method I've seen is the standard loop. Let me give you an example:
    Simba Code:
    program woodChopper;

    procedure cutTrees;
    begin
      writeLN('[procedure] cutTrees');
    end;

    procedure walkToBank;
    begin
      writeLN('[procedure] walkToBank');
    end;

    procedure bankLogs;
    begin
      writeLN('[procedure] bankLogs');
    end;

    procedure returnToTrees;
    begin
      writeLN('[procedure] returnToTrees');
    end;

    begin
      repeat
        cutTrees;
        walkToBank;
        bankLogs;
        returnToTrees;
      until false;
    end.
    This can work for some situations. However, if anything unexpected happens, it can often break the script. Say, for whatever reason, it fails to bank the logs. It's got to run through 3 other procedures before hopefully fixing the issue.

    Scan and React


    This is exactly like it sounds. You scan, and then you react accordingly. I can try to explain it, but since most people learn by example:
    Simba Code:
    program fighter;

    var
      vDropModelID:array of uInt32=[123456,456789,789123];
      vMonsterModelID:uInt32=987654321;
      vProcedure:procedure();

    procedure pAttackMonster;
    var
      canAttack:countDown;
      monsterModels:glModelArray;
    begin
      repeat
        monsterModels:=ogl.getModels(vMonsterModelID).getVisible();
        if canAttack.isFinished() and length(monsterModels) then
        begin
          mouse.rightClickOption(monsterModels.closestTo(ogl.getClientMidPoint())[0],'Attack');
          canAttack.setTime(1000);      
        end;
      until combat.hasTarget() or monsterModels.isEmpty();
    end;

    procedure pLookForMonster;
    var
      canLook:countDown;
      monsterModels:glModelArray;
    begin
      repeat
        monsterModels:=ogl.getModels(vMonsterModelID).getVisible();
        if canLook.isFinished() and monsterModels.isEmpty() then
        begin
          mainScreen.setDegrees(random(360),random(20,50));
          canLook.setTime(3000);      
        end;
      until not monsterModels.isEmpty();
    end;

    procedure pTakeDrop;
    var
      canTake:countDown;
      dropModels:glModelArray;
    begin
      repeat
        dropModels:=ogl.getModels(vDropModelID).getVisible();
        if canTake.isFinished() and length(dropModels.isEmpty()) then
        begin
          mouse.rightClickOption(dropModels.closestTo(ogl.getClientMidPoint())[0],'Take')
          canTake.setTime(1000);      
        end;
      until dropModels.isEmpty();
    end;

    begin
      repeat
        if length(ogl.getModels(vDropModelID)) then //~ Scan
          vProcedure:=@pTakeDrop //~ React
        else if length(ogl.getModels(vMonsterModelID)) and (not combat.hasTarget()) then //~ React
          vProcedure:=@pAttackMonster //~ React
        else if ogl.getModels(vMonsterModelID).isEmpty() then  //~ React
          vProcedure:=@pLookForMonster //~ React

        ogl.callProcedure(@vProcedure);
      until false;
    end.

    That's about it. As I haven't dealt with color, apart from just recently using getColor(), but it's great for OpenGL.

    Hope this helps some people!
    Last edited by Obscurity; 07-16-2015 at 01:13 AM.




    Skype: obscuritySRL@outlook.com

  2. #2
    Join Date
    May 2012
    Location
    Glorious Nippon
    Posts
    1,011
    Mentioned
    50 Post(s)
    Quoted
    505 Post(s)

    Default

    Nice tutorial! I appreciate that it's short and to the point.

    I guess I use the 'standard' loop, but I 'scan' on the first line of each procedure so that it exits if the 'scan' doesn't check out.
    e.g. my abyss rc mainloop
    Simba Code:
    procedure mainLoop();
    begin
      bank();
      runToMage();
      clickThings();
      chargePouches();
      enterAltar();
      craftRunes();
    end;
    can be started at any point along the way, so it's just a matter of where you want to put those scans.
    I'll definitely give this method a shot and see how I like it.

  3. #3
    Join Date
    Jun 2012
    Posts
    586
    Mentioned
    112 Post(s)
    Quoted
    296 Post(s)

    Default

    Thanks to Turpinator showing me how to get a procedure name from a pointer, I've edited the original post.

    Rather then include a....
    Simba Code:
    writeLN('[procedure] someProcedure')
    ...in each procedure, you can check if the pointer is nil (and thus doesn't contain a procedure), and if it's not then use...
    Simba Code:
    if @vProcedure<>nil then
      begin
        writeLN(ogl.getUpTime(),' > someScriptName > ',replaceRegExpr('procedure\(\)\s\("([\w]+)"::0x[A-F0-9]+\)',toStr(@vProcedure),'$1',true));
        vProcedure();
      end;
    Code:
    12:34:56 > ogLib > pTakeDrop
    Last edited by Obscurity; 07-09-2015 at 08:21 PM.




    Skype: obscuritySRL@outlook.com

  4. #4
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default

    This is interesting. My scripts are all traditional loop-based scripts, but individual routines are structured in such a way that if anything goes wrong, looping through the rest of the routines won't be an issue.

    Taking your example: say my banking routine fails and my logs aren't banked. Of course, the main loop will proceed to call the following routines (and, in eventuality the preceding ones as well) but they will simply exit once they check the inventory and realize that it is full.

    Once the loop goes full circle (which I'd imagine only takes a few milliseconds because all of the routines simply exit), we can try banking again.

    How does this compare to the way you've done it in the OP / second post?

    E: Just saw Citrus' post. We do the same thing. How does this type of traditional loop compare to what you've done (which to me looks like a variation on a finite-state machine)?
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Bad™ before everyone gets laser pistols

  5. #5
    Join Date
    Jun 2007
    Location
    The land of the long white cloud.
    Posts
    3,702
    Mentioned
    261 Post(s)
    Quoted
    2006 Post(s)

    Default

    I think the 'standard' loop achieves the same thing if you do it properly, and is much easier for people to understand. I know most/all of the scripts for java bots I've seen use a similar FSM style loop, and I've seen a few scripts here over the years, but I guess it's just up to the scripter what they use.

    E: Here is Bumblebeee's tutorial https://villavu.com/forum/showthread.php?t=58300
    Last edited by The Mayor; 07-09-2015 at 09:25 PM.

  6. #6
    Join Date
    Oct 2006
    Posts
    6,752
    Mentioned
    95 Post(s)
    Quoted
    532 Post(s)

    Default

    Quote Originally Posted by The Mayor View Post
    I think the 'standard' loop achieves the same thing if you do it properly, and is much easier for people to understand. I know most/all of the scripts for java bots I've seen use a similar FSM style loop, and I've seen a few scripts here over the years, but I guess it's just up to the scripter what they use.
    Agreed, plus IMO this is a easier to understand FSM style loop..
    “The long-lived and those who will die soonest lose the same thing. The present is all that they can give up, since that is all you have, and what you do not have, you cannot lose.” - Marcus Aurelius

  7. #7
    Join Date
    Jun 2007
    Location
    The land of the long white cloud.
    Posts
    3,702
    Mentioned
    261 Post(s)
    Quoted
    2006 Post(s)

    Default

    Quote Originally Posted by elfyyy View Post
    Agreed, plus IMO this is a easier to understand FSM style loop..
    I just edited my post the exact same time as you quoted me

  8. #8
    Join Date
    Dec 2011
    Location
    East Coast, USA
    Posts
    4,231
    Mentioned
    112 Post(s)
    Quoted
    1869 Post(s)

    Default

    Quote Originally Posted by The Mayor View Post
    I think the 'standard' loop achieves the same thing if you do it properly, and is much easier for people to understand. I know most/all of the scripts for java bots I've seen use a similar FSM style loop, and I've seen a few scripts here over the years, but I guess it's just up to the scripter what they use.

    E: Here is Bumblebeee's tutorial https://villavu.com/forum/showthread.php?t=58300
    I agree. Finite-state machines are no doubt a higher-level programming technique, but (at least for the purposes of RS macroing) I don't see a huge advantage over traditional loops.
    GitLab projects | Simba 1.4 | Find me on IRC or Discord | ScapeRune scripts | Come play bot ScapeRune!

    <BenLand100> we're just in the transitional phase where society reclassifies guns as Bad™ before everyone gets laser pistols

  9. #9
    Join Date
    Jun 2007
    Location
    The land of the long white cloud.
    Posts
    3,702
    Mentioned
    261 Post(s)
    Quoted
    2006 Post(s)

    Default

    I also think that if you are going to go down the whole 'states' route, then the state needs to be set within a method that changes the state, and not calculated within one procedure. For example, if you clicked a monster, then you would set the global state to 'attacking', within the attacking procedure. The way this is structured is essentially a 'standard main loop' except instead of calling the procedure directly, you assign it to a pointer, and then call the procedure through that pointer. E.g:

    Simba Code:
    begin
      repeat
        if length(ogl.getModels(vDropModelID)) then //~ Scan
          vProcedure:=@pTakeDrop //~ React
        else if length(ogl.getModels(vMonsterModelID)) and (not combat.hasTarget()) then //~ React
          vProcedure:=@pAttackMonster //~ React
        else if ogl.getModels(vMonsterModelID).isEmpty() then  //~ React
          vProcedure:=@pLookForMonster //~ React
        else
          vProcedure:=@pDoNothing; //~ React
        if @vProcedure<>nil then
          begin
            writeLN(ogl.getUpTime(),' > someScriptName > ',replaceRegExpr('procedure\(\)\s\("([\w]+)"::0x[A-F0-9]+\)',toStr(@vProcedure),'$1',true));
            vProcedure();
          end;
      until false;
    end.

    If you got rid of all the pointers (and the empty procedure) then you could just do this:

    Simba Code:
    begin
      repeat
        if length(ogl.getModels(vDropModelID)) then
          pTakeDrop()
        else if length(ogl.getModels(vMonsterModelID)) and (not combat.hasTarget()) then
          pAttackMonster()
        else if ogl.getModels(vMonsterModelID).isEmpty() then
          pLookForMonster();
      until false;
    end.

  10. #10
    Join Date
    May 2012
    Posts
    499
    Mentioned
    23 Post(s)
    Quoted
    228 Post(s)

    Default

    I liked how @hoodz used a 'scan and react method' in his NMZ script found here:
    https://villavu.com/forum/showthread.php?t=113041
    I just think multiple 'if then else' doesn't look clean, I don't like reading scripts like that either.
    But like @The Mayor said, it just unneeded code for most part.

  11. #11
    Join Date
    Sep 2012
    Location
    Netherlands
    Posts
    2,752
    Mentioned
    193 Post(s)
    Quoted
    1468 Post(s)

    Default

    Quote Originally Posted by Thomas View Post
    I liked how @hoodz used a 'scan and react method' in his NMZ script found here:
    https://villavu.com/forum/showthread.php?t=113041
    I just think multiple 'if then else' doesn't look clean, I don't like reading scripts like that either.
    But like @The Mayor said, it just unneeded code for most part.
    maybe a better example is HoodzFighter, thats more complicated.

Thread Information

Users Browsing this Thread

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

Posting Permissions

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