• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Math function instead of hashtable save/load?

Status
Not open for further replies.
Level 12
Joined
Nov 3, 2013
Messages
989
this might not strictly be wc3 related per se but can you somehow get a math function from a series of values to use instead of hashtable?

I'd normally use a hashtable and have a & b as keys while c would be the saved/loaded value.

But since the values are static/ won't change I thought it should work to just have some polynomial function or something that make "a[n] & b[n] -> c[n]".

Tried looking for a program that creates a function that uses a series of input values to create a function w/ google but no success there.

Basically hashtable is better than checking through series of values repeatedly but doing some calculation should be even more superior if you can do that instead...
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
I don't really understand what you were saying but I think that this is something you want:

If you have a low preset amount of rows that your hashtable uses and they all use the same storage type, you can split arrays.

Lets imagine that you want to save integers for every player.
There are 12 players in the map so you need a table with 12 rows.
That is a low preset amount and it is an integer every time so we use arrays.

"Integer[playerId + maxplayers*index]"
The first 12 variables are index 1 for player 1-12.
The second 12 variables are index 2 for player 1-12.
The third 12 variables are index 3 for player 1-12.
etc. etc. etc.

The problem is that next to that you can only save one variable type, you devide the array size (imaginary) by 12.
I thought that the max was somewhere just below 8.4k so the max now will be 8.4k / 12 = 670.
So you could have very small arrays if you use more things than 12.

However if this is not what you were looking for, then I suggest you to explain a bit better.
 
Level 12
Joined
Nov 3, 2013
Messages
989
I.E. if with a hashtable I'd save/load value 10 in parent key 4 and child key 79 then instead through the math function when a = 4 and b = 79 then c = 10.

and at the same time if a = 45 and b = 0 then c could be equal to 9999

(I'm just making up random numbers because the actual numbers aren't relevant, the entire point would be to make a function, which obviously won't be linear, have variable c be related to a and b)

So basically it would work like a 2d table like a hashtable but since all the entries are fixed there's nothing that's going to change so it seems stupid to have to load values when I should just be able to use a polynomial function or something like it.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
So something like this?
JASS:
function CSaveInteger takes hashtable whichHashtable, integer parent, integer child returns nothing
    local integer value = parent + child
    call SaveInteger(whichHashtable, parent, child, value)
endfunction

But your solution would be like this:
JASS:
function GetYourRequestedInteger takes nothing returns integer
    return 9999
endfunction

Unless you want to use this instead:
JASS:
globals
    integer YourRequestedInteger = 9999
endglobals

EDIT: However none of them can be used in GUI.
With one exception that you can get the data from the hashtable in GUI.
 
Level 12
Joined
Nov 3, 2013
Messages
989
JASS:
function Trig_items_init_Copy_Actions takes nothing returns nothing
    set udg_item_id[0] = 'I000'
    set udg_item_id[1] = 'I001'
    set udg_item_id[2] = 'I002'
    set udg_item_id[3] = 'I003'
    set udg_item_id[4] = 'I004'
    set udg_item_id[5] = 'I005'
    set udg_item_id[6] = 'I006'
    set udg_item_id[7] = 'I007'
    set udg_item_id[8] = 'I008'
    set udg_item_id[9] = 'I009'
    set udg_item_id[10] = 'I00A'
    set udg_item_id[11] = 'I00B'
    set udg_item_id[12] = 'I00D'
    // so on and so forth
endfunction

Now over half of the array would be saved in a hash table with parent and child keys consisting of the previous half or so.

SaveInteger(hash, udg_item_id[a], udg_item_id[b], udg_item_id[c])

But instead I thought since it's not dynamic I could just have an equation that use the a and b index directly to get c without any save/load in any hash table and just use one single integer array.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Yea it is supposed to stop when there are no items left.
However Death Adder (or the user) should replace that 'IA00' with the latest item.
In that way, you have the 8k lines (if you have 8k items) in those 4 lines.
You reduce your writing by 99.95% ... I thought I would be helpfull :D

You can also add this line exitwhen id > 8191 next to the one you already have.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
This appears to be best done with a binary search tree, which is an ordered collection. If a binary tree isn't enough, then a quad tree definitely will be. I am not able to write self-balancing trees though, that stuff is beyond my understanding.

Another option is using your own hashing function that maps to values 1-8191. However, this would have more impact on performance than hashtables and thus, not worth it for this purpose.
 
Level 12
Joined
Nov 3, 2013
Messages
989
This appears to be best done with a binary search tree, which is an ordered collection. If a binary tree isn't enough, then a quad tree definitely will be. I am not able to write self-balancing trees though, that stuff is beyond my understanding.

I understand having this kind of sorting would be required if the entries were dynamic, but all the integers and their index will remain the same after map init where they are declared.

My train of thought was that since I don't even have to look at the actual integers and just use the index directly, since I already know what they contain 100% of the time, I should be able to use a calculation (which I'm assuming would be faster) instead of checking for the integers' values (even in the case where they are sorted) or loading from hash.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
If somehow you could maintain the arithmetic progression of your object Ids then you can use an offset computation:

JASS:
    set udg_item_id[0] = 'I000'
    set udg_item_id[1] = 'I001'
    set udg_item_id[2] = 'I002'
    set udg_item_id[3] = 'I003'
    set udg_item_id[4] = 'I004'
    set udg_item_id[5] = 'I005'
    set udg_item_id[6] = 'I006'
    set udg_item_id[7] = 'I007'
    set udg_item_id[8] = 'I008'
    set udg_item_id[9] = 'I009'
    
    set OFFSET=udg_item_id[0]
...

function GetObjectIndex takes integer objectId returns integer
    return objectId-OFFSET
endfunction

EDIT: Eh, wait... I think I misunderstood the question, sorry.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
I understand having this kind of sorting would be required if the entries were dynamic, but all the integers and their index will remain the same after map init where they are declared.

My train of thought was that since I don't even have to look at the actual integers and just use the index directly, since I already know what they contain 100% of the time, I should be able to use a calculation (which I'm assuming would be faster) instead of checking for the integers' values (even in the case where they are sorted) or loading from hash.

The thing is that vJASS is lacking the feature for precompiling lists. I could do this because I have an unofficial addition, but I am not aware of other ways for resolving it at compiletime.
 
Status
Not open for further replies.
Top