• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[GUI] [How To] Arrays

Level 22
Joined
Jul 25, 2009
Messages
3,091
All right then, let's get started. I don't like to take long amounts of time to read about learning something I could learn much faster myself from experience, or from images, test maps, etc. I assume you are probably the same way.

So I'll make it quick.



1. Explanation: Arrays are based on positive integers of any value between 0 and 8191. (an integer is a solid whole number like 1 or 2) Each integer in an array is basically a copy of the variable itself. (meaning, it holds similar information) Hashtables work equally as well, but arrays are normally more efficient and accessible. In this example I show you a tid-bit of the possibilities of arrays:
  • Ultra Generic Trigger Is Generic
    • Events
      • Player - Player 1 (Red) types a chat message containing -start as An exact match
      • Player - Player 2 (Blue) types a chat message containing -start as An exact match
      • Player - Player 3 (Teal) types a chat message containing -start as An exact match
      • Player - Player 4 (Purple) types a chat message containing -start as An exact match
      • Player - Player 5 (Yellow) types a chat message containing -start as An exact match
    • Conditions
    • Actions
      • Set Players[(Player number of (Triggering player))] = (Triggering player)


2. Uses: Instead of making a variable for every player on a team, like Player1Red, Player2Blue, etc. You can just make a variable based on "Player" and give it an array. (This in my opinion is much better than a player group or Hashtables) See 3. for implementation.
  • The Most Generic Trigger Possible
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set Players[1] = Player 1 (Red)
      • Set Players[2] = Player 2 (Blue)
      • Set Players[3] = Player 3 (Teal)
      • Set Players[4] = Player 4 (Purple)
      • Set Players[5] = Player 5 (Yellow)
      • -------- VS --------
      • Set Player1Red = Player 1 (Red)
      • Set Player2Blue = Player 2 (Blue)
      • Set Player3Teal = Player 3 (Teal)
      • Set Player4Purple = Player 4 (Purple)
      • Set Player5Yellow = Player 5 (Yellow)


3. Implementation: If you are trying to set the integers in an array with one integer for each player like I was saying above, you can do what I did in the trigger below. Setting them like this could take some time, and you can use a looping integer instead, but that won't be something I explain in this tutorial (You can see the looping integer under FAQ at the bottom of the page). Not useful to you yet? See 4.
  • Generic Trigger
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set Players[1] = Player 1 (Red)
      • Set Players[2] = Player 2 (Blue)
      • Set Players[3] = Player 3 (Teal)
      • Set Players[4] = Player 4 (Purple)
      • Set Players[5] = Player 5 (Yellow)

4. Simple Uses: You could create an array variable if you didn't want to make several variables of the same type. See the trigger below for an example. It is much better than a variable for each type of damage. You can apply this to anything from Unit Groups to Special Effects for a spell.
  • More Generic Trigger
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set DamageTypes[1] = Normal
      • Set DamageTypes[2] = Enhanced
      • Set DamageTypes[3] = Fire
      • Set DamageTypes[4] = Cold
      • Set DamageTypes[5] = Poison

FAQ:
#1_____________________________________________________
Q: How can I use this aside from with players and simple stuff?

A: The possibilities are too extreme for me to describe all of them, but unit or item Custom Values could be used. One great example is from indexing systems, which you can look up in our spells section.

#2_____________________________________________________
Q: How can I loop through an array?

A: Create any looping integer function, and set it up like so. It might look a little bit complicated, but it is easy to understand if you think about it. The numbers "from 1 to 5" represent the integers of your array that you will manage. For example, if you want to loop through your array X times, the loop will be from 1 to X (or 0 to X). Keep in mind that arrays can only have an index from 0-8191, because arrays are limited to 2^13 individual indices. Generally, try to keep your index values low so you won't run into any problems. The following example will assign the variable "Players" to each player from 1 to 5. (each index of "Players" will be assigned to the corresponding player)
  • Looping Stuff
    • Events
      • Time - Elapsed game time is 15.00 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 5, do (Actions)
        • Loop - Actions
          • Set LoopInt[(Integer A)] = (Integer A)
          • Set Players[LoopInt[(Integer A)]] = (Player(LoopInt[(Integer A)]))
#3_____________________________________________________
Q: What should the array be set to?

A: The number of things you are indexing, if you are following my example of setting using Player Number of Triggering Player, you would have 1 integer for each player, which if you had 12 players, would be 12, so that's what you set the array to. Most people skip this step, and just leave it at 1, (World Editor's script adds the rest of the numbers as your triggers do), but I think you should set it like I said, to the number of things you are indexing. I stated earlier the maximum of the Array is 8191, it cannot exceed that, see FAQ #2 for more explanation on this subject.



THANKS FOR READING! :D
 
Last edited by a moderator:
Level 37
Joined
Mar 6, 2006
Messages
9,240
About hashtables vs arrays, hastables are much better at some scenarios. For example if you create an item system. You save item types into an array, and then something else into another array like damage.

You'd need to find out the item type, which array index it is saved to. You would have to loop through the array to get the index. If you have 80 item types, you'd do the check 40 times on average.

However by using a hastable, you could initialize the needed data using the item type id's, so you would only need a single hastable action to load the needed data.

Much better than doing 40 checks. Arrays, hashtables and player groups all have their purpose.
 
Level 22
Joined
Jul 25, 2009
Messages
3,091
Nowhere do you explain that WC3 arrays are dynamic arrays. Nor do you explain the index range (0 to 8191). You did not mention the apparent map save bug with index 8191.

@SuperGood
1. I had no idea 8191 was the highest range.
2. I don't think mentioning a save bug would really pertain to the situation, this is really just for noobs like me, when I figured out how to index triggering got so much more complex.
3. I'm not sure what relevancy that has? But if it means that much I will post links to the different types of arrays.

@Maker
1. I know all about Hashtables. They have positives, but I haven't used them much since I started coding. Most people say Arrays are faster too.
 
1. I know all about Hashtables. They have positives, but I haven't used them much since I started coding. Most people say Arrays are faster too.

When it comes to spells, arrays are faster, but if you're going to use an array for data storage that requires a search, hashtables could be up to 4096 times faster if the array is full.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Considering spells, it's also good to remeber that using hashtables isn't automatically x times slower since there are a lot of other actions in there also.

If a hashtable save/load is 4-8x slower than an array save/load, the spell might still be less than 1.5x slower for example.

It all depends on the spell.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
The whole reason a hashtable is so slow compared to an array is due to the jass inperpreter.

1 hashstable read needs atleast...
4 names passes (1 function and 3 parameters)
1 native evaluated

1 array read needs
2 names passed (1 variable and 1 index)

This is not including other names that may or may not need to be passed such as GetHandleId. The JASS interpereter is just really bad at efficiency.
 
The tutorial is nice for a brief introduction, and I have updated it to make some of the information less controversial. (or rather, less subject to a need for fixing)

A: The number of things you are indexing, if you are following my example of setting using Player Number of Triggering Player, you would have 1 integer for each player, which if you had 12 players, would be 12, so that's what you set the array to. Most people skip this step, and just leave it at 1, (World Editor's script adds the rest of the numbers as your triggers do), but I think you should set it like I said, to the number of things you are indexing. I stated earlier the maximum of the Array is 8191, it cannot exceed that, see FAQ #2 for more explanation on this subject.

You may want to fix the answer for this. When you set a "size" of an array, it just will initialize each variable with index 0 up until "size". For integers and reals, it will set each array (from 0 to "size") to 0, for booleans "false", and "null" for most other things. This is just an added safety so that when you try to read an array that hasn't been set yet, it won't end the thread. (aka, stop the trigger from finishing its actions)

You don't have to add such a detailed example, but anything kind of explaining the reasoning a bit more will do.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
@SuperGood
2. I don't think mentioning a save bug would really pertain to the situation, this is really just for noobs like me, when I figured out how to index triggering got so much more complex.

No offense but this kind of tutorial is already for noobs.
And this bug is really evil, even if i'm agree most of the time you won't use the index 8191, it's still good to know.

3. I'm not sure what relevancy that has? But if it means that much I will post links to the different types of arrays.

It is simply the nature of the arrays in jass, it's really important, even if in high level languages (included interpreted ones such as jass) arrays are often (always ?) dynamic.
 
Top