• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] Base

Simple and extremely short script for creating any length and variety of base type.

Technically it looks like it supports ASCII, however inefficient.

JASS:
Base["................................ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~."]

However, I2S(52913) should just be "52913" and BJDebugMsg("") is fine for a demo map and hides the true ugliness that is DTTTP.
 
A version that uses Table, marginal speed decrease but definitely helps to stay shy of the 255 hashtable limit.

JASS:
library Base requires Table
    //struct Base extends array
    //-------------------------------------------
        //static method operator [] takes string base returns thistype
        //method to takes integer i returns string
        //method from takes string i returns integer
        
        //method ord takes string c returns integer
        //method char takes integer i returns string
        
    globals
        private TableArray TA
        private TableArray TR
        private Table TB
        private integer c = 0
        private integer array s
    endglobals
    
    private module M
        static method operator [] takes string base returns thistype
            local integer value = StringHash(base)
            local thistype this = TB[value]
            local Table ta
            local Table tr
            local string char
            
            if (integer(this) == 0) then
                set this = c + 1
                set c = this
                
                set TB[value] = this
                set value = StringLength(base)
                set s[this] = value
                
                set ta = TA[this]
                set tr = TR[this]
                loop
                    set value = value - 1
                    set char = SubString(base, value, value+1)
                    set ta[StringHash(char)] = value
                    set tr.string[value] = char
                    exitwhen value == 0
                endloop
            endif
            
            return this
        endmethod
        
        method to takes integer i returns string
            local integer k = s[this]
            local string n = ""
            local Table t = TR[this]
            loop
                exitwhen i < k
                set n = t.string[i - i / k * k] + n
                set i = i/k
            endloop
            return t.string[i] + n
        endmethod
        
        method from takes string i returns integer
            local integer n = 0
            local integer p = StringLength(i)
            local integer l = 0
            local integer k = s[this]
            local Table t = TA[this]
            loop
                exitwhen p == 0
                set p = p - 1
                set l = l + 1
                set n = n + t[StringHash(SubString(i, l - 1, l))] * R2I(Pow(k, p))
            endloop
            
            return n
        endmethod
        
        method ord takes string c returns integer
            return TA[this][StringHash(c)]
        endmethod
        method char takes integer i returns string
            return TR[this][i]
        endmethod
        method operator size takes nothing returns integer
            return s[this]
        endmethod
        private static method onInit takes nothing returns nothing
            set TA = TableArray[8191]
            set TR = TableArray[8191]
            set TB = Table.create()
        endmethod
    endmodule
    
    struct Base extends array
        implement M
    endstruct
endlibrary
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
It not only compiles, but it works >.>.

The script's fine. There is another way to do this with no hashtable, but this way is smarter.

edit
Nevermind, just came up with a way that can replace the hashtable with a table. I'll update it today.

The hashtable itself points to an array of values. So one large range (requiring 1 full index) and one limited range. That array of values can also be put into a stack inside where the hashtable points to the pointer of that stack. This means then that only 1 full index is required, thus a Table can be used instead of a hashtable if using a stack instead of an array =).

Should be slightly faster and still have a max instance count of 8191.

edit
The reason a TableArray was because it wasn't needed for this. A TableArray would be useful if I had like a 3D collection (my array + table array).
 
The efficiency comparison we were talking about is set up as:

table[tableInstance] (a Table array)

tableArrayInstance + tableInstance (a TableArray)

I'm still not convinced on the efficiency difference. An array lookup versus simple addition, I think we need some better benchmarks on this (not those "stopwatch" natives as those are really inaccurate, more like that FPS check you used with TimerQueue or the manual stopwatch approach that D4RK_G4ND4LF uses)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS math must then, almost certainly, work similar to Python math (call an __add__ method instead of just bitwise-shifting). But I would still like to see some non-RTC benchmarks on this so I can know for sure.

It's already been benched. Iterating over a linked list is faster than iterating over an array.

There have been 3 benches of it, all with varying results (depending on the exitwhen).
 
Top