HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Function takes array??? How???

08-24-2006, 01:09 AM#1
GALLED
Hello everybody, can i do a function that takes an array (integer for example??) How???

Thanks in advance.
08-24-2006, 01:22 AM#2
karukef
No.
08-24-2006, 01:26 AM#3
Wyvernoid
Hello^^
Maybe you can fit the arrays into arrays, forming a 2-D array like arrayname[intA][intB]... and then, make the function take an intA, that is equivalent to giving the function the array "arrayname[intA]".
Try it, dunno if executable ;-)
08-24-2006, 01:33 AM#4
PipeDream
You can only pass indexes to global arrays. Using some tricks for partitioning those arrays it can be faked effectively. Here's an example from something I'm working on:

Collapse JASS:
//
//Fibonacci series.  To get a block of size <right number> alloc(<left number>)
//0 1
//1 2
//2 3
//3 5
//4 8
//5 13
//6 21
//7 34
//8 55
//9 89
//10 144
//11 233
//12 377
//13 610
//14 987
//15 1597
//16 2584
//17 4181
//18 6765

//globals
//	location array udg_pool
//	integer array udg_heap
//	integer array udg_fib
//	integer udg_cmpi1
//	integer udg_cmpi2
//endglobals
function ItoR takes integer i returns real
    return i
    return 0.
endfunction
function HtoR takes handle h returns real
    return h
    return 0.
endfunction
function ItoL takes integer i returns location
    return i
    return null
endfunction
function RtoL takes real r returns location
    return r
    return null
endfunction
function RtoI takes real r returns integer
    return r
    return 0
endfunction

//this version of EvaluateBoolexpr written by Weaaddar
function EvaluateBoolexpr takes boolexpr bx returns boolean
    local trigger t=null// CreateTrigger()
    local triggercondition tc=null // call TriggerAddCondition( t, bx)
    local boolean b=true
    if(bx==null)then
        return b
    endif
    set t=CreateTrigger()
    set tc=TriggerAddCondition(t,bx)
    set b=TriggerEvaluate(t)
    call TriggerRemoveCondition(t,tc)
    call DestroyTrigger(t)
    set tc=null
    set t=null
    return b
endfunction

//size is the exponent of 2
//Push the block into the appropriate list
function free takes integer begin, integer size returns nothing
    set udg_pool[size] = Location(ItoR(begin),HtoR(udg_pool[size])) 
endfunction

//udg_pool is an array of lists of free blocks of size 2^i
function initheap takes nothing returns nothing
    local integer i = 0
    local integer max = 8191    //Becuase of that silly bug with saving
    local integer j = 0
    set udg_fib[0] = 1
    set udg_fib[1] = 2
    loop
        exitwhen i > 18
        set udg_fib[i+2] = udg_fib[i]+udg_fib[i+1]
        set i = i + 1
    endloop
//	call BJDebugMsg(I2S(udg_fib[18]))

    set i = 18
    loop    //Greedily chop up our heap
        exitwhen i < 0
        if j + udg_fib[i] > max then    //Bit off more than we can chew
            set i = i - 1
        else                        //Send the block off to the pool
            call free(j,i)
            set j = j + udg_fib[i]
        endif
    endloop
endfunction


function alloc takes integer size returns integer
    local integer block
    local location next
//First check if we have a block of appropriate size
    if udg_pool[size] != null then
        set block = RtoI(GetLocationX(udg_pool[size]))
        set next = RtoL(GetLocationY(udg_pool[size]))
        call RemoveLocation(udg_pool[size])
        set udg_pool[size] = next
        set next = null
    else    //We're out of block of the right size
        if size >= 18 then    //Biggest fib we could possibly have
            call BJDebugMsg("Error, out of memory-gamecache me")
            return -1
        endif
        set block = alloc(size+1)    //Get the next in the series
        if size == 0 then //Block size 2 gets split into 1 and 1
            call free(block+1,0)
        else   //split a block of size f(n+1) into f(n) and f(n-1)
            call free(block+udg_fib[size],size-1)    //e.g. block 8 goes into block of 5 and block 3
        endif
    endif
    return block    //Hand back the bottom part
endfunction

//Selection is a little bit faster but it is unstable
function selectionsort takes integer arr, integer size, trigger compare returns nothing
    local integer i = 0
    local integer j
    loop
        exitwhen i >= size

        set udg_cmpi1 = udg_heap[arr+i]

        set j = i
        loop
            exitwhen j >= size
            set udg_cmpi2 = udg_heap[arr+j]
            if not TriggerEvaluate(compare) then
                set udg_heap[arr+i] = udg_cmpi2
                set udg_heap[arr+j] = udg_cmpi1
            endif
            set j = j + 1
        endloop

        set i = i + 1
    endloop
endfunction

function insert takes integer arr, integer i, integer val, trigger compare returns nothing
    local integer j = arr+i - 1
    loop
        set udg_cmpi1 = udg_heap[j]
        set udg_cmpi2 = val
        exitwhen TriggerEvaluate(compare)
//		exitwhen udg_heap[j] <= val
        set udg_heap[j+1] = udg_heap[j]
        set j = j - 1
        exitwhen j < arr
    endloop
    set udg_heap[j+1] = val
endfunction

function insertionsort takes integer arr, integer size, trigger compare returns nothing
    local integer i = 1
    local integer j
    local integer val
    loop
        exitwhen i>=size

        set j = arr + i - 1
        set val = udg_heap[arr+i]
        set udg_cmpi2 = val
        loop
            set udg_cmpi1 = udg_heap[j]
            exitwhen TriggerEvaluate(compare)
            set udg_heap[j+1] = udg_heap[j]
            set j = j - 1
            exitwhen j < arr
        endloop
        set udg_heap[j+1] = val


//		call insert(arr,i,udg_heap[arr+i],compare)
        set i = i + 1
    endloop
endfunction
//merge sort for long arrays
function sort takes integer arr, integer size, trigger compare returns nothing
    local integer len1
    local integer len2

    local integer array temp 
    local integer i
    local integer a    //index in low array
    local integer b //index in high array
    if(size < 15) then
        call insertionsort(arr,size,compare)
    else
        set len1 = size / 2
        set len2 = size - len1
        call sort(arr,len1,compare)
        call sort(arr+len1,len2,compare)
        set a = arr
        set b = arr+len1
        set len1 = b
        set len2 = b+len2
        set i = 0
        set udg_cmpi1 = udg_heap[a]
        set udg_cmpi2 = udg_heap[b]
        loop
            exitwhen i >= size

            if a < len1 and (b >= len2 or TriggerEvaluate(compare)) then
                set temp[i] = udg_cmpi1
                set a = a + 1
                set udg_cmpi1 = udg_heap[a]
            else
                set temp[i] = udg_cmpi2
                set b = b + 1
                set udg_cmpi2 = udg_heap[b]
            endif
            set i = i + 1
        endloop

        set i = 0
        loop
            exitwhen i>= size
            set udg_heap[arr+i] = temp[i]
            set i = i + 1
        endloop
    endif
endfunction

Collapse JASS:
function FillArrayWithGroup takes integer arr, integer max, group g returns integer
    local unit u
    local integer i = 0
    loop
        exitwhen i >= max
        set u = FirstOfGroup(g)
        exitwhen u == null
        set udg_uheap[arr+i] = u
        set i = i + 1
    endloop
    return i
endfunction

function FillUdist takes integer arr, integer len, real x, real y returns nothing
    local integer i = 0
    local real ux
    local real uy
    loop
        exitwhen i >= len
        set ux = GetUnitX(udg_uheap[arr+i]) - x
        set uy = GetUnitY(udg_uheap[arr+i]) - y
        set udg_rheap[arr+i] = ux*ux+uy*uy
        set i = i + 1
    endloop
endfunction

function FillPermVec takes integer arr, integer len returns nothing
    local integer i = 0
    loop
        exitwhen i>= len
        set udg_heap[arr+i] = arr+i
        set i = i + 1
    endloop
endfunction

function FillGroupWithPermutedArray takes group g, integer arr, integer size, integer max returns nothing
    local integer i = 0
    if size > max then
        set size = max
    endif
    loop
        exitwhen i>= size 
        call GroupAddUnit(g,udg_uheap[udg_heap[arr+i]])
        set i = i + 1
    endloop
endfunction

function compare_units takes nothing returns boolean
    return udg_rheap[udg_heap[udg_cmpi1]] <= udg_rheap[udg_heap[udg_cmpi2]]
endfunction

//Add 5 closest units to a group
function Trig_sort_uloc_Actions takes nothing returns nothing
    local group g = CreateGroup()
    local integer arr
    local integer n

    local boolexpr b
    local trigger t
    local triggercondition tc

    local real x = 0.
    local real y = 0.

    call initheap()
    set arr = alloc(10)
    call GroupEnumUnitsInRange(g,x,y,1000000.,null)
    set n = FillArrayWithGroup(arr,100,g)    //this removes everything in the group
    call FillPermVec(arr,n)
    call FillUdist(arr,n,x,y)

    set b = Condition(function compare_units)
    set t = CreateTrigger()
    set tc = TriggerAddCondition(t,b)

    call sort(arr,n,t)

    call FillGroupWithPermutedArray(g,arr,n,5)

    call free(arr,10)
    call TriggerRemoveCondition(t,tc)
    call DestroyTrigger(t)
    call DestroyBoolExpr(b)
    set t = null
    set tc = null
    set b = null

    call DestroyGroup(g)
    set g = null
endfunction

//===========================================================================
function InitTrig_sort_uloc takes nothing returns nothing
    set gg_trg_sort_uloc = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_sort_uloc, Player(0) )
    call TriggerAddAction( gg_trg_sort_uloc, function Trig_sort_uloc_Actions )
endfunction

Game cache is another option which is rather easier to use but about 5x slower.
08-24-2006, 01:12 PM#5
GALLED
So i must make a global variable and insert de indexs into the function??
08-25-2006, 03:58 AM#6
PipeDream
Yes. There are automated ways to do this, one way is using the top snippet. It's an extremely inconvenient interface though. You can check out CSCache for something which takes care of some of the arithmetic. If you can wait to write those triggers for a week or two I expect a couple different ways to do it easily to appear...
08-25-2006, 01:31 PM#7
Toadcop
Quote:
GALLED
-it's impossible with standart War3

PipeDream - lol why you are using TriggerEvaluate =) ? a new ultra cool data storing sys, i like this ! i must make also some new stuff =)