• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

3D arrays?

So, I know Hashtables can be used for 2D arrays, but I am curious if there's a GUI friendly way to have something like vJass Table with N-Dimensional Arrays?

My need is to have a data structure where I can save multiple information tied to an ability that is owned by a Unit, there will be multiple abilities and multiple units, with each Unit being possible to have multiple instances of calculation for the same ability. Sort of like a Timed Ability library that handles the intricate aspects of object editor abilities.

To be clear, I don't think Almia's Timed Ability fits with what I need, and closest I can think of is Bannar's Timed Stack, but it treats abilities as stacks, where I don't want the stacks aspect, instead saving the level for each instance to adjust when a higher instance is depleted before a lower instance does.

Any suggestion is appreciated! 👍
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Same pattern can be generalized:

[a][b][c]..[N] = a*Sum(Asize .. (N-1)size) + b*Sum(Bsize .. (N-1)size) + c*Sum(Csize .. (N-1)size) + .. + N

Where indices are in the range 0 .. (size-1). Yes this is more annoying to work with for 1-indexed arrays but you really just need to add some strategic +1s and -1s. 0-indexed example for 3 dimensions:

[a][b][c] = a*(bsize+csize) + b*csize + c

Use a hashtable, man. One of its purposes is to make situations like this easier to work with.
 
+1 to the above (and fun-fact, that's how they are implemented under the hood when you have an array instance variable in a struct), but I imagine it is going to be a bit cumbersome to write out in GUI (and the numbers will probably get quite large--possibly in the integer overflow territory--if you're trying to work with ability raw-codes and such directly).

Truthfully though, most of the options will be a bit annoying to write in GUI. :grin: But in situations like this, I think it is always good to ask yourself a few questions to decide what data structure is best for you:
  1. Is this for a system/spell to submit, or something specific for your map? (sometimes if you are coding just for your own map, you can make more specific assumptions--which often simplifies things quite a bit)
  2. Do you need more than 3-dimensions?
  3. How many "instances" do you think will be active at a given time? (on the order of 10? 100? 1000s?)
My understanding is that you have a relationship as Unit -> Ability -> List of ability instances, which is why you might feel like a 3D-array set-up would be useful. But I think if you give a bit more info on what you're trying to do, we could give some alternatives that might be a bit simpler! It's definitely possible to do but it can quickly get painful to debug/maintain in GUI.

For example, let's say you were coding a one-off spell that drops down a totem, but you only want three totems to be active max. If someone casts it when three totems are already down, you want to remove the oldest one. If you don't expect there to be a ton of these units on the map, it honestly might be fine to just use normal dynamic indexing--and then just loop through the list of active spell instances to replace the oldest totem. Especially since you only have that "searching" cost when the spell is cast.

But if you wanted this to be a generic system, or something you need to look-up frequently in a periodic trigger, then it might be worth optimizing it further. Maybe if you give us more details or an example of a spell that you'd like to store info for, we could give some suggestions? :)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,285
Another approach to multi-dimensional arrays is to generate a hash from all the indices and use that to lookup a linked list or binary tree from a bucket array. You can search that linked list/binary tree for the correct entry for the supplied indices. Using the binary tree approach would give a worst case complexity of O(log2(n)) while keeping index sizes unbounded, which is likely one of the best achievable complexities. When the bucket array is sparsely populated, and assuming a hash algorithm that has good entropy, the lookup complexity will be close to O(1) with performance mostly dictated by the hash algorithm.

Hashtables likely do something like this internally.
 
Top