PDA

View Full Version : Functions - Creating and using them.



Sandstorm
12-10-2008, 05:19 AM
Functions. Creating them, using them.



Table of Contents:

Introduction.
Creating a function.

Turning a procedure into a function.
Starting from scratch
Using the returned result in a script.
Conclusion.



Introduction:

*Note - I know my standards are a little off, so don't quote me on them.

Functions. For a long while, I had no idea what they were or how they were used. After I learned, I found them to be VERY useful.

Functions have many uses, from returning True/False in a While Do statement, to finding the midpoint of a set of numbers.

A function is basically a procedure that returns a result. This result can be used to do just about anything, as long as the types are the same.

Here's an example of what a Function is:

Function IsLog(InvSpot : integer) : Boolean;
Var
P : Tbox;
Begin
GetInvItemBounds(InvSpot, p);
Result := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85;
End;

This is an excerpt from my Firemaking script. What it does is it checks if the number of black dots in a given area is 85. If it is, then it returns true, if not, then it returns false.


The things that really make a function a function, are these two lines, as they are the only two that are unique to functions:


Function IsLog(InvSpot : integer) : Boolean; //Declares it as a function.

Result := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; //Returns the value of the function, be it true or false.


Let's break it down now.

Function - Tells the script it's a function, and it can return a value.

IsLog(InvSpot : integer) - Same as a procedure would use. Declares the name and parameters.

: Boolean; - Tells the script the result will be a boolean

Result := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; //Returns the value of the function, be it true or false.

Result := - Declares what the Result will be. Makes the function return whatever is after this line.

CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; - Counts the number of dots with the color 65536 in the specified area. If it equals 85, then the function returns true. If not, it returns false.

More on this later.

Creating a function.

Creating a function is actually very similar to creating a procedure, with one main difference. A function frees up a variable.

There's two main things you can do to make a Function. Turn a procedure into a function (only if you use a variable to check something later on, in the procedure), and start from scratch.

I'll start with turning a procedure into a function:

Program New;
{.include srl/srl.scar}
Var
I : Boolean;

Procedure IsLog(InvSpot : integer); //Declares it as a Procedure
Var
P : Tbox;
Begin
GetInvItemBounds(InvSpot, p);
I := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; //Returns the value of the I, be it true or false.
End;

Begin
SetupSrl;
IsLog(1)
If I Then
WriteLn('It''s a log!');
End.

Let's turn that into the function I posted earlier.

To do that, we need to change a few things:

First of all, we need to let the script know that it's a Function, not a Procedure:


Function IsLog(InvSpot : integer) : Boolean; //Declares it as a function.
Var
P : Tbox;
Begin
GetInvItemBounds(InvSpot, p);
I := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; //Returns the value of the function, be it true or false.
End;

Second, we need to add in the use of Result:


Function IsLog(InvSpot : integer) : Boolean; //Declares it as a function.
Var
P : Tbox;
Begin
GetInvItemBounds(InvSpot, p);
Result := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; //Returns the value of the function, be it true or false.
End;

Next, we have to remove the variable I, as it isn't used, and instead put IsLog in there:

Program New;
{.include srl/srl.scar}

Function IsLog(InvSpot : integer) : Boolean; //Declares it as a function.
Var
P : Tbox;
Begin
GetInvItemBounds(InvSpot, p);
Result := CountColor(65536, p.x1, p.y1, p.x1+34, p.y1+27) = 85; //Returns the value of the function, be it true or false.
End;

Begin
SetupSrl;
If IsLog(1) Then //Runs the IsLog Function, and checks if there's a log in slot one or not.
WriteLn('It''s a log!');
End.

It looks sleeker, doesn't it? There's also one less global variable in use, and I believe that saves memory.

Now, let's focus on creating a function from scratch.

To start, you want to decide on a name, and what it will return, plus if it has parameters. Let's call it NewFunction, and we'll make it return an integer, and we'll make it have two parameters, X1, and Y1, which will both be integers.

Function NewFunction(X1, Y1 : Integer) : Integer;
Begin
End;

Now, we have to decide what we want it to do. To start, let's make it return the middle of the two parameters.

To do that, we want to tell it that the result equals the middle of the two parameters. The math formula for that is X1 + Y1 / 2 = Result. To implement that into scar, we need to add a variable, because scar is picky about the way it uses math.

For example:

Function NewFunction(X1, Y1 : Integer) : Integer;
Begin
Result := X1 + Y1 / 2;
End;


Will return a different value then this, which is the working function:

Function NewFunction(X1, Y1 : Integer) : Integer;
Var
P : Integer;
Begin
P := X1 + Y1; //Makes P equal X1 + Y1.
Result := P / 2; //Makes the Function return X1 + Y1 / 2.
End;

And there you go. You have a fully working function that will tell you the middle of two integers.

How to use the value of a Function in a script.

Using the result of a function in a script is not all that different then using a Variable, except that you don't have to set the variable every time it needs to be changed, you just call the function again, and it will adjust if it needs to.

Let's use the example function we made in the last section.

Currently, we have this, or something like it (strictly speaking, we don't need to include srl for this to work, but I like to get into the habit of including it):

Program New;
{.include srl/srl.scar}

Function NewFunction(X1, Y1 : Integer) : Integer;
Var
P : Integer;
Begin
P := X1 + Y1; //Makes P equal X1 + Y1.
Result := P / 2; //Makes the Function return X1 + Y1 / 2.
End;

Begin
SetupSrl;
End.

But that isn't enough to get it to return a value!

To do that, we need to call the function, which may sound just like a procedure, but they aren't called in the same way at all.

If we were to use that as a procedure, and have it return the finished product to the variable I, we would need to do this:

NewFunction(10, 20);
WriteLn(IntToStr(I));

But functions don't use a variable that you declare, so you use them like this:

WriteLn(IntToStr(Newfunction(10, 20)));

It does the same thing, but saves some space and saves a variable.

In the end, you should have something like this:

Program New;
{.include srl/srl.scar}

Function NewFunction(X1, Y1 : Integer) : Integer;
Var
P : Integer;
Begin
P := X1 + Y1; //Makes P equal X1 + Y1.
Result := P / 2; //Makes the Function return X1 + Y1 / 2.
End;

Begin
SetupSrl; //Sets up srl, not needed.
WriteLn(IntToStr(Newfunction(10, 20))); //Calls the NewFunction function, and writes in what the result of it is.
End.

Conclusion:

Functions can be used for many different things, from checking if a screen is up, to seeing if it's time to run a procedure. The result can be many different types, from strings and integers, to booleans and variants.

All things considered, my opinion is that Functions are better than Procedure in some cases. I hope you came out of this tutorial having learned something, even if you won't use it in your scripts.

I hope you now know how to create and use a function, as well as change a procedure into a function.

~Sandstorm

P.S. - This was written at 10 at night, so if theres any errors, please point them out :).

Kyle Undefined
12-11-2008, 02:32 AM
21 view 0 replies. I'll be your first. This looks like it will help alot of new scripters out in creating functions. :D

~Camo

Sandstorm
12-11-2008, 03:02 AM
Thanks for the reply Camo, see any more errors? :P.

Magiic
12-17-2008, 05:09 PM
apart from maybe the standards in the function :p but yeah it's all gd :P

Naum
12-17-2008, 05:15 PM
Amazing, very indepth.
Rep++, your tuts dont leave me un-noticed :)

Sandstorm
12-17-2008, 10:35 PM
Wow, thanks guys!

It's my first tut (decent one...., my last one was like "Do this: Ok, your good" lol), so I didn't expect it to be that great :o.

~Sandstorm

Andyz55
12-24-2008, 05:53 AM
Great tut sand. I was looking for a tut on functions. Rep+ for you.

-Andy

boberman
12-24-2008, 01:37 PM
Yikes, you do some bad practices with you functions.

For example, MMouse(TpointFunction.X, TpointFunction.Y, 3, 3)

If you are calling the function more then once but expecting the same result, you should almost always save it off in another variable. Why? What if something changes in between the first and second call? All the sudden, the data from TpointFunction becomes worthless. Just like that.

Also, it avoids a fair amount of overhead. It is much easier to use the result more then once then to try and generate it each time you want to use it.

It would have been nice if you specifically mentioned when to make a function/procedure. A fair amount of beginner scripters don't understand encapsulation and why it is important.

All in all, it is a good tutorial for understanding the how, and even to some extent the why. Now add something about the When and you should have yourself a killer tutorial.

Sandstorm
12-24-2008, 07:27 PM
Yea, I guess your right on the tpoint area. I didn't notice that lol :/.

I'll take a look into the "when", and fix up the tpoint part, because I guess it's kind of useless, lol.


Also, it avoids a fair amount of overhead. It is much easier to use the result more then once then to try and generate it each time you want to use it.

It would have been nice if you specifically mentioned when to make a function/procedure. A fair amount of beginner scripters don't understand encapsulation and why it is important.


Mind explaining that more? Lol :/. Oh, I get the first part now lol.

Thanks for the feedback, again, I'll look into it.

I actually just removed the whole TPoint part of it.

@Andyz - No problem!

~Sandstorm

pk ownage94
12-24-2008, 07:38 PM
Very useful tutorial Ill refer back to this countless times.:)
Before I read this I didn't really understand how the hell you use functions to walk around etc, now I understand thanks to you :)
REP+!

thanks,

-PK;)