# [JASS]2d simple jass array?

Status
Not open for further replies.

#### Legend_Dk

Level 3
Just as the title says is it possible to make a 2d array in the simple jass ?
For the first instance i need it to make a quest array for all the players, and secondly i need it for an item table Thanks in advance

#### Starquizer

Level 16
Just as the title says is it possible to make a 2d array in the simple jass ?
For the first instance i need it to make a quest array for all the players, and secondly i need it for an item table Thanks in advance
In vJASS it is possible.

#### GhostWolf

Level 29
Or you can handle the correct indexing alone, but there is no reason to reinvent the wheel.

#### Yixx

Level 16
Yes, in vJass it is possible. But it is, as all vJass, an illusion. If you know how to correctly handle a normal array, 2d array is within inimaginable reach of you.

#### DiscipleOfLife

Level 9
It is pretty simple. For example, if you want to have a 2d array where one index is a player's id, you can do:
JASS:
``````function Set2D takes integer playerId, integer secondIndex, <type> value returns nothing
set udg_myVar[playerId + 16 * secondIndex] = value
endfunction
function Get2D takes integer playerId, integer secondIndex returns <type>
return udg_myVar[playerId + 16 * secondIndex]
endfunction``````
Here the 16 comes from the fact that player ids range from 0 to 15 (to my recollection).

If you want to understand why this works, you can stare at the results of the [playerId + 16 * secondIndex] function and see how it doesn't generate overlapping indexes i.e. numbers in the third column occur only once for the given values:
 playerId secondIndex playerId + 16 * secondIndex 0 0 0 0 1 16 0 2 32 0 3 48 0 4 64 0 5 80 0 6 96 0 7 112 0 8 128 0 9 144 0 ... ... 1 0 1 1 1 17 1 2 33 1 3 49 1 4 65 1 5 81 1 6 97 1 7 113 1 8 129 1 9 145 1 ... ... 2 0 2 2 1 18 2 2 34 2 3 50 2 4 66 2 5 82 2 6 98 2 7 114 2 8 130 2 9 146 2 ... ... ... ... ...

#### Legend_Dk

Level 3
Thanks to you all, and especially DiscipleOfLife, thanks for the solutions +rep

#### Storyyeller

Level 6
Wait, aren't there only 12 players, not 16? I'm confsued.

#### Ciebron

Level 11
a good hint, get Newgen!. Will make your life easier.

#### Starquizer

Level 16
It is pretty simple. For example, if you want to have a 2d array where one index is a player's id, you can do:
JASS:
``````function Set2D takes integer playerId, integer secondIndex, <type> value returns nothing
set udg_myVar[playerId + 16 * secondIndex] = value
endfunction
function Get2D takes integer playerId, integer secondIndex returns <type>
return udg_myVar[playerId + 16 * secondIndex]
endfunction``````
Here the 16 comes from the fact that player ids range from 0 to 15 (to my recollection).

If you want to understand why this works, you can stare at the results of the [playerId + 16 * secondIndex] function and see how it doesn't generate overlapping indexes i.e. numbers in the third column occur only once for the given values:
 playerId secondIndex playerId + 16 * secondIndex 0 0 0 0 1 16 0 2 32 0 3 48 0 4 64 0 5 80 0 6 96 0 7 112 0 8 128 0 9 144 0 ... ... 1 0 1 1 1 17 1 2 33 1 3 49 1 4 65 1 5 81 1 6 97 1 7 113 1 8 129 1 9 145 1 ... ... 2 0 2 2 1 18 2 2 34 2 3 50 2 4 66 2 5 82 2 6 98 2 7 114 2 8 130 2 9 146 2 ... ... ... ... ...

This is a 2d array; the variable still carry 1 index whatever its value is.

Int[j] is not Int2[i + 16*j]

#### Ciebron

Level 11
looks like a 2d array too me, takes 2 integers. its a pre-newgen 2d array

Last edited:

#### Starquizer

Level 16
looks like a 2d array too me, takes 2 integers. its a pew-newgen 2d array
How ? I don't understand. 2d arrays must have 2 indexes, its what I used in other programing language to make a matrix.

In the table you created an equation inside the [] that will result in different number when you change the 2 variables it consists of but it is a single array still.

#### GhostWolf

Level 29
How ? I don't understand. 2d arrays must have 2 indexes, its what I used in other programing language to make a matrix.

In the table you created an equation inside the [] that will result in different number when you change the 2 variables it consists of but it is a single array still.

That's how a 2D array works under the surface.
You don't just tell your compiler to put something at [4][3] and it magically stores it somewhere.
A 2D array is a normal array just with some calculations (the above) that tell it where to store/get things.

I am pretty sure, though, they usually do it in blocks and not spread like that (as in i * Max + j).
This makes more sense as it allocates a block for each 'i'.

And in case you don't see how that makes a 2D array, say you want a 4x4 array, the first index is [0][0] which will turn into 0*4+0 = 0.
The second index is [0][1] which will turn into 0*4+1 = 1.
The last index is [3][3] which will turn into 3*4+3 = 15.

And so on and on.

The exact same thing happens for any dimension above one, but it gets more and more messy.

#### Starquizer

Level 16
That's how a 2D array works under the surface.
You don't just tell your compiler to put something at [4][3] and it magically stores it somewhere.
A 2D array is a normal array just with some calculations (the above) that tell it where to store/get things.

I am pretty sure, though, they usually do it in blocks and not spread like that (as in i * Max + j).
This makes more sense as it allocates a block for each 'i'.

And in case you don't see how that makes a 2D array, say you want a 4x4 array, the first index is [0][0] which will turn into 0*4+0 = 0.
The second index is [0][1] which will turn into 0*4+1 = 1.
The last index is [3][3] which will turn into 3*4+3 = 15.

And so on and on.

The exact same thing happens for any dimension above one, but it gets more and more messy.
And this applies to any array in any programing language or in JASS scripting only ?

#### Eleandor

Level 21
Yes.

In some low-level programming languages you get much more power over arrays. For example: in C arrays can be used as pointers. A pointer *points* to a memory adress in your RAM memory. Arrays effectively are pointers to an adress. The calculation is very simple:

Say "array" points to adress 1000. Say it's an array of "integers", this means every integer is 4 bytes large.
array[0] points to 1000 + 0*4 = 1000
array[1] points to 1000 + 1*4 = 1004
array[2] points to 1000 + 2*4 = 1008
etcetera.

If it would be an array of long integers (8 bytes - this type doesn't exist in warcraft), then it would be very similar:
array[0] points to 1000 + 0*8 = 1000
array[1] points to 1000 + 1*8 = 1008

A 2D array can be seen as an "array of arrays"". So if you have an array of long integers (8 bytes) of maximum size 4x4, you get:
array[0,0] points to 1000 + (0*4*8) + (0*8) = 1000
array[0,1] points to 1000 + (0*4*8) + (1*8) = 1008
array[0,2] points to 1000 + (0*4*8) + (2*8) = 1016
array[0,3] points to 1000 + (0*4*8) + (3*8) = 1024
array[1,0] points to 1000 + (1*4*8) + (0*8) = 1032
As you can see, the 2D array is just like the 1D array a pointer to a memory adress, where the index specifies an offset from that adress. In the case of multiple indices, each index specifies their own offset from the starting adress.

#### Starquizer

Level 16
Yes.

In some low-level programming languages you get much more power over arrays. For example: in C arrays can be used as pointers. A pointer *points* to a memory adress in your RAM memory. Arrays effectively are pointers to an adress. The calculation is very simple:

Say "array" points to adress 1000. Say it's an array of "integers", this means every integer is 4 bytes large.
array[0] points to 1000 + 0*4 = 1000
array[1] points to 1000 + 1*4 = 1004
array[2] points to 1000 + 2*4 = 1008
etcetera.

If it would be an array of long integers (8 bytes - this type doesn't exist in warcraft), then it would be very similar:
array[0] points to 1000 + 0*8 = 1000
array[1] points to 1000 + 1*8 = 1008

A 2D array can be seen as an "array of arrays"". So if you have an array of long integers (8 bytes) of maximum size 4x4, you get:
array[0,0] points to 1000 + (0*4*8) + (0*8) = 1000
array[0,1] points to 1000 + (0*4*8) + (1*8) = 1008
array[0,2] points to 1000 + (0*4*8) + (2*8) = 1016
array[0,3] points to 1000 + (0*4*8) + (3*8) = 1024
array[1,0] points to 1000 + (1*4*8) + (0*8) = 1032
As you can see, the 2D array is just like the 1D array a pointer to a memory adress, where the index specifies an offset from that adress. In the case of multiple indices, each index specifies their own offset from the starting adress.
I can't say that I comletely understand but do you know of any site that can illustrate this more precisly.

#### Starquizer

Level 16
array[0,0] points to 1000 + (0*4*8) + (0*8) = 1000
array[0,1] points to 1000 + (0*4*8) + (1*8) = 1008
array[0,2] points to 1000 + (0*4*8) + (2*8) = 1016
array[0,3] points to 1000 + (0*4*8) + (3*8) = 1024
array[1,0] points to 1000 + (1*4*8) + (0*8) = 1032

I understand now how they point to a specific address but the number 4,8 I don't know why we use those specific numbers ?

#### GhostWolf

Level 29
You use the size of the data type you are storing in the array because Eleandor is talking about the actual bytes that the array is stored in.

A normal integer is 4 bytes long, so it makes sense that every index takes 4 bytes.
A short integer is 2 bytes long, so it makes sense that every index takes 2 bytes.

Same goes for any size.

#### Starquizer

Level 16
You use the size of the data type you are storing in the array because Eleandor is talking about the actual bytes that the array is stored in.

A normal integer is 4 bytes long, so it makes sense that every index takes 4 bytes.
A short integer is 2 bytes long, so it makes sense that every index takes 2 bytes.

Same goes for any size.
Normal integers like 1,2,3,4 .... they are as binary stored in those bytes ?

#### GhostWolf

Level 29
Say you have a character variable (a character is a...well, a character, for example 'a', '1', etc).
A character takes 1 byte, this means that it looks like this when it is equal to zero:
(b = binary, 0x = hex, d = decimel)

00000000b
0x00
0d

Now say you make it equal to 4, it will look like this

00000100b
0x04
4d

It always takes exactly one byte so it can be between -127 and 127 (forget unsigned integers for now)

01111111b
0x7F
127d

Now say you have an array of characters {0,1,2,3,4,5,6} at the address 1000, it would look like this (hex for short text)

Code:
``````Address: 1000 1001 1002 1003 1004 1005 1006
Offset:  00   01   02   03   04   05   06
Value:   00   01   02   03   04   05   06``````

The same thing applies for integers or any data type, just they are bigger.
A Warcraft integer is 4 bytes, which is

00000000000000000000000000000000b
0x00000000

Meaning that if you have the same array but with integers, it will look like this
Code:
``````Address: 1000 1004 1008 1012 1016 1020 1024
Offset:  00   04   08   0C   10   14   18
Value:   00   01   02   03   04   05   06``````

#### Dr Super Good

Spell Reviewer
Level 64
You could also use a HashTable as a 2D array as it axcepts 32 bit signed integers for both its keys. Although this logically will be slower.

#### Starquizer

Level 16
It always takes exactly one byte so it can be between -127 and 127 (forget unsigned integers for now)

01111111b
0x7F
127d

128 will be

10000000b
0x 80
128d

Isn't that supposed to count as 1 byte also ?

#### GhostWolf

Level 29
128 will be

10000000b
0x 80
128d

Isn't that supposed to count as 1 byte also ?

You can only put 128-255 if the variable is unsigned (it has no minus).
This is because if it is signed, the last bit is there to determine the sign, 1 for minus and 0 for plus (although there are also those who do 0 for minus and 1 for plus).

Signed:
10000000b = -0

Unsigned:
10000000b = 128

#### Starquizer

Level 16
That is very useful indeed , where did you learn all this programing stuff ?

#### Dr Super Good

Spell Reviewer
Level 64
You can get limateless 2D arrays. Whereby you can pass any number, even negatives as indexes as get as specific storage location. However this is a process of hashing and is a lot, lot and lot slower than normal 2D arrays as they require multiple comparisons and loops to find the right place in the array (as well as other operations). Welcome to HashTables which take 2 integers and return a unique value (storage location).

Thus for speed you are forced to go with fixed size arrays in JASS. In other languages however you can use dynamic sized 2D arrays which are basically arrays of arrays. Speed wise I am not certain, but they may be faster or slower depending on caching and opperations like array bond checks. They however are more memory intensive as they have pointers to other parts in the memory which hold the data rather than directly storing the data.

Basically you difine an array of a certain size of arrays. You then can create an array of values in that array slot of any size. This works because the first array refers to another arrays and so does not store the data in a continous and mathimatically logical way. As you have probably figured, this means that the arrays can end up anywhere in memory and so the additional memory reading can cause slowdowns if not cached. This however is a prety decent way to do 2D arrays as it still keeps direct efficency and allows some degree of size varience.

For example using this method 0 might refer to an array of size 16 of value.
1 on the other hand might refer to an array of size 1024.
2 may refer to an array of size 10.
Using this system 0:11, 1:959 and 2:5 are all valid storage locations. However 0:16 exceeds the array size.

This can be used to store data more dynamically than other methods. It saves on storage space if there are a couple of indexes which need a large number of second index space as you can difine only the space needed and do not have to have to allocate space that will never be used. It also allows the extension of the array easier. If you want to expand index 0 from size 16 to size 32, using the other mathimatical method of 2D arrays it would require the rebuilding of the whole array which can be many 1000 entries, each needing to be moved to new locations which takes time while with the nested arrays you simply rebuild the second level array which requires the duplication of only 16 entries.

As you can see this is also a completly viable way and would be great for some spells in WC3. Sadly blizzard did not allow you to difine arrays on the fly in JASS like JAVA, C++ and other languages do so you are stuck with mathimatical 2D arrays of fixed indexes or HashTable emulated 2D arrays.

#### Starquizer

Level 16
Is the HashTable a program or a tecnique that allows me to create 2D arrays ?

#### Dr Super Good

Spell Reviewer
Level 64
Its a set of new natives able to be interfaced in GUI and directly with JASS.

#### Eleandor

Level 21
It's a new type of variable. You need patch 1.24 to be able to use it

#### GhostWolf

Level 29
Using a hash table for a 2D array is so conceptually wrong...

#### Element of Water

Level 18
Well a programmer's gotta use what a programmer's got available.

#### Dr Super Good

Spell Reviewer
Level 64
Not entirly true. Hashes are designed to store stuff with 2 indexes thus it to the triggerer appears as a 2 level array system lol.

Yes though, for speed based 2D work it is totally wrong to use hashes, as they are designed for coping with a huge range of numbers, not lots of numbers.
If only Blizzard allowed for lower level array manipulation, then this would not be a problem.

You could then do something like "set array[1][2] = 1" easilly as array[1] has the value of another array which you can then directly pass another index into.

Status
Not open for further replies.

[Trigger] 2d-array in GUI?
Replies
5
Views
1K
[Trigger] 2d integer array?
Replies
5
Views
836
Replies
17
Views
2K
Replies
4
Views
977
[vJASS] array value?
Replies
9
Views
1K