SRL Archive - OSR Advanced Scripting Tutorials

Multi Dimensional Arrays !!! - 1st Full tutorial


Enslaved

2013-05-26 11:58:16

Multi Dimensioning in simba – First Full Multi-dim Tutorial on SRL


Intro:
With this tutorial I assume you know the basics of arrays so here goes :p

Multi-Dimension is like an arrays of arrays. Or lists containing lists, and lists containing lists containing lists. This is probably one of the most useful things you are going to learn and is closely linked to Object orientated programming
Now to get multiple dimensions to work you need to first declare the multi dimension array.
And you do it like this: in this example I am going to do it of a TPAs


Var
ATPA: Array of TpointArray;
//or

Var
AATPA: Array of Array of TpointArray;

Alternatively you can also set predefined lengths of these arrays

Var
ATPA: Array [0..5] of TPointArray;
//Or
AATPA: Array [0..5] of Array [0..5] of TpointArray;

After you defined the Array, you will need to write to it.
First of all, lets start off By defining our ATPA

Var
TPA: Array [0..4] of Tpoint;
ATPA: Array of Array of Tpoint; // or ATPA: Array of TPointArray; aka T2DPointArray
Begin
TPA[0] := [Point(0,0)];
TPA[1] := [Point(5,10), Point(10,4), Point(5,3)];
TPA[2] := [Point(3,3), Point(91,2),Point(59,52),Point(15,12)];
TPA[3] := [Point( 123, 921), Point(1,1)];
TPA[4] := [Point(999,999)];
ATPA := TPA;
//Or
ATPA[0][0] := Point(0,0);
ATPA[1][0] := Point(5,10);
ATPA[1][1] := Point(10,4);
ATPA[1][2] := Point(5,3);
ATPA[2][0] := Point(3,3);
//and so on… …
End.

There We go, We just Defined out first 2 dimensional Array.
As you can see, that each TPA contains an array of TPoints. Well how does this make it useful you ask. Well now you can select a TPointArray.

Start of Multi Dimensioning
Now I know you can do this by assigning each TPA to like TPA1, TPA2, TPA3, but this is so much more versatile.

Multi Dimension Commands
SetLength:
This sets the length of the arrays or certain dimensions.

SetLength(Array,New_Length);
This is used when you what to change the size of said Array/Dimension, This is also known in some languages as the Re-Dimension Command. You can use it to change the size of your array with it
Example:
SetLength(TPA,5);
With this it is adding the option to use TPA[5];
Well what about if you want to change the length of a specific TPA?
Well then you would use this:
Say you want to enlarge TPA[0], well then you would simply do
SetLength(TPA[0], NEW_LENGTH);


Similarly for The length Functions:
Length(TPA)
Would return the no of objects under TPA, ie TPA[j], it would return i
Whist Length(TPA) would return j

High(TPA) is much the same, but with 1 lower than Length(TPA)
And would return the highest index value.


Now the versatility:
Multi Dimensions does not have to be with TPAs, It can also have a variety of other uses like giving things attributes.
For Example you can give Variables Values of things:
Var
Item: Array [0..4] of Variant;
Begin
Item[0] := ‘Rune Pickaxe’;
Item[1] := ColorOfRunePick;
Item[2] := [Uptexts];
Item[3] := Weight;
Item[4] :- LevelReq;
End;


See with one item it might be useful, that is your single dimension array
With Multi-Dimensional Arrays you can build up an item index



Var
ItemIdx : array [0..1] of array [0..4] of Variant
Begin
ItemIdx[0][0] := ‘Rune Pickaxe’;
ItemIdx[0][1] := ColorOfRunePick;
ItemIdx[0][2] := [Uptexts];
ItemIdx[0][3] := Weight;
ItemIdx[0][4] :- LevelReq;
ItemIdx[1][0] := ‘Adamant Pickaxe’;
ItemIdx[1][1] := ColorOfRunePick;
ItemIdx[1][2] := [Uptexts];
ItemIdx[1][3] := Weight;
ItemIdx[1][4] :- LevelReq;
End;
or via this method:

Var
RunePick,AdPick: Array [0..4] of variant;
Itemidx: Array of Variant;
begin
RunePick[0] := ‘Rune Pickaxe’;
RunePick[1] := ColorOfRunePick;
RunePick[2] := [Uptexts];
RunePick[3] := Weight;
RunePick[4] :- LevelReq;
AdPick[0] := ‘Adamant Pickaxe’;
AdPick[1] := ColorOfAdPick;
AdPick[2] := [Uptexts];
AdPick[3] := Weight;
AdPick[4] :- LevelReq;
Itemidx := [runepick,adpick];
End.


Notice I did only assigned Itemidx to be 1 dimensional but by assigning an array to an array, it transforms the array to be multidimensional.

Now with these it can be really annoying trying to remember all the index values if you are so now I bring you to indexing.
The only way to index things in Simba is by using defining index labels as constants.
This is done by



Const
I_Rune = 0;
I_Ad = 1;
I_Name = 0;
I_Color = 1;
I_Up = 2;
I_Weight = 3;
I_Req = 4;
Var
RunePick,AdPick: Array [0..4] of variant;
Itemidx: Array of Variant;
begin
RunePick[I_Name] := ‘Rune Pickaxe’;
RunePick[I_Color] := ColorOfRunePick;
RunePick[I_Up] := [Uptexts];
RunePick[I_Weight] := Weight;
RunePick[I_Req] :- LevelReq;
AdPick[I_Name] := ‘Adamant Pickaxe’;
AdPick[I_Color] := ColorOfAdPick;
AdPick[I_Up] := [Uptexts];
AdPick[I_Weight] := Weight;
AdPick[I_Req] :- LevelReq;
Itemidx := [runepick,adpick];
End.
//so
If (ItemIDX[I_Rune][I_Name] = ‘Rune Pickaxe’) then
Writeln(ItemIDX[I_Rune][I_Name]);


Summary:

Multi-Dimensional arrays basically Nested in each other, you can treat them the same :)
The only difference is you can stick the Multi-Dimensional one in a loop statement :)
Also When Assigning Treat TPA[0] the same As if you where using TPA0.
Length functions return the number of things under it in a single level not the entire thing.

If you have any questions on usage, please don’t hesitate to ask me!!!
you can reach me on Skype: Enslavedm , PM or reply here!!!


Example of my untested color function including multi-dimensional arrays

Function TPDist(P1,P2:TPoint):Integer;
begin
Result := Distance(P1.x,P1.y,P2.x,P2.y);
end;


Function MultiColorDist(Colors,Tol,Maxdist:Array of LongInt;x1,y1,x2,y2:Integer):TpointArray; // Main Color to look for followed by surrounding colors
//Written by Enslaved
Var
i,j,k:integer;
TPAMain, ReturnTPA: TPointArray;
ColTPAA: Array of TPointArray;
TPACount : Array of Integer;
Begin
If High(Colors) <> High(tol) then
Begin
Writeln('Uneven array lengths');
Result := [];
Exit;
end;
If (High(Colors) <> (High(MaxDist) + 1)) then
Begin
Writeln('Make sure that the length of Max Dist is 1 less that of the colors');
Writeln('Current MaxDist Length:' + IntToStr(Length(MaxDist)));
Writeln('Current Color Items:' + IntToStr(Length(Colors)));
Result := [];
Exit;
end;
If (High(colors) = 0) then
begin
Writeln('Please search for more than 1 color');
result := [];
Exit;
End;

If FindColorsSpiralTolerance(Round((X1+x2)/2),Round((Y1+Y2)/2),TPAMain,Colors[0],x1,y1,x2,y2,Tol[0]) then
Begin
SetLength(TPACount,Length(TPAMain));
SetLength(ColTPAA,Length(Colors));
For i := 1 To High(Colors) do
FindColorsSpiralTolerance(Round((X1+x2)/2),Round((Y1+Y2)/2),ColTPAA[i],Colors[i],x1,y1,x2,y2,Tol[i]);

For i := 0 To High(TPAMain) do
Begin
For j := 1 to High(ColTPAA) do
Begin
For k := 0 to High(ColTPAA[j]) do
Begin
If (TPDist(ColTPAA[j][k],TPAMain[i]) <= MaxDist[j-1]) then
Begin
TPACount[i] := TPACount[i] + 1;
Break;
End;
End;
End;
If (TPACount[i] = High(ColTPAA)) Then
begin
TPACount[i] := 1;
end else
TPACount[i] := 0;
end;
End;
j := 0;
For i := 1 to High(TPAMain) do
Begin
If (TPACount[i] = 1) then
Begin
SetLength(ReturnTPA,(j + 1));
ReturnTPA[j] := TPAMain[i];
end;
End;
Result := ReturnTPA;
End;
end;

samerdl

2013-05-27 12:01:38

very nice man, thank you this is quiet useful

Itankbots

2013-05-27 12:23:35

O damn, sweet! Im falling asleep, but ill read it tomrrow, only skimmed now :P

I love Tpa;s , never used arrays tho :(

Edit: I get the concept, but in what situation would arrays benefit you? Like how do they save time or more efficient then Just making a normal TPA for an item.

Only thing i can think of is mass listing of items, for like a Ge-flipper.

If you could give me some examples of where this would be used and what situation, would help me understand more :)

Enslaved

2013-05-27 17:50:58

@Itankbots
my example was an array of an tpa, in other words a T2DPointArray, I used it whilst cycling through when searching for multiple colors. ofc the code is unoptimised(v slow as i didnt trim the TPA of the colors down and it is rather inefficient as it is going through every permutation of points);

The most common use for these are when having a non static count of similar objects. for example if you are making a ball game, you would naturally assign each ball to a variable and make that an array of data that is relevant to the ball, for example, colour ,size, x,y co-ordinates and other properties. But the trouble with that is that you would have to alter the code every time you add a new item or define an extremely large stack of variables that will not be used -> inefficient. this way you can generate each "object" within the for loop and also assign attributes to it.

Basically much like normal arrays, where you would loop through each item in a TPA to check all of them. but what if you have multiple TPAs? well then you would use a nested for loop to loop through each TPA for Each color ( if looking for multiple colors), of course there are other ways to go about this, but it would be an extremely useful skill to know if you wish to expand on your knowledge.

I would recommend you learn this just for future reference, as in my background (physics and mathematics) and most forms of data processing it opens up a very powerful tool to use.

As for your questions on TPAs, if you plan on using more than 1 TPA in a function then this would be the way to go :)

footballjds

2014-01-15 16:52:10

glad you wrote a guide to help out.
LOL at the fact that someone who joined in 2012 is claiming to have written the first multidimensional array guide… Guess the rest of us learned via osmosis ;)

From: Itankbots
I love Tpa;s , never used arrays tho :(


a tpa is an array, by definition and literally. TPA means TPointArray, an array of TPoints(x and y's).

TPA's and ATPA(arrays of TPA's) are going to be your friend if you ever do advanced item/object recognition. if done correctly you can have the same accuracy as using a bmp to search with the speed of instant.

An array is useful because you're stringing together values that relate to one another. If it weren't for arrays we couldn't use a for loop to loop through arrays.