HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Sorting Algorithim woes

12-26-2003, 03:59 PM#1
weaaddar
Actually its strings of number. Strings are used so I know when the array terminates, (I suppose I could give only integers an escape value but strings seemed easier). Anyway I'm looking for an algorithim to sort them any of you have any ideas?

I just need a function I can call like Sort() which will take nothing and return a boolean stating if it suceeded (it moved something) or if it failed (it didn't move anything). It also will always work on the same string array so I have no need for an input variable. The array in question is udg_ItemArray
12-26-2003, 05:17 PM#2
Vidstige
Wouldn't it be easier to just use an integer array and store the length of it in a variable?
It feels like the sorting would be much easier then...
12-26-2003, 06:22 PM#3
weaaddar
Its much harder as at any instance multiple items can be added/removed at different area and without this method I've no idea what the true length is.
12-26-2003, 07:12 PM#4
KaTTaNa
I gave it a shot.. here is a function, I gtg go now but I'll complete it later (this one always returns true, but should sort correctly).
Code:
// Made by KaTTaNa
function IsBefore takes string A, string B returns boolean
    if ( B == null ) or ( B == "" ) then
        return true
    endif
    if ( S2I(A) > S2I(B) ) then
        return false
    endif
    return true
endfunction

function Sort takes nothing returns boolean
    local boolean moved = true
    local boolean found
    local integer i = 0
    local integer p
    local integer q
    local string array result 
    loop
        exitwhen (udg_ItemArray[i] == "") or (udg_ItemArray[i] == null)
        set found = false
        set p = 0
        loop
            exitwhen p > i
            if ( IsBefore(udg_ItemArray[i], result[p] ) ) then
                set q = i
                loop
                    exitwhen q < p
                    set result[q+1] = result[q]
                    set q = q - 1
                endloop
                set result[p] = udg_ItemArray[i]
                set found = true
                exitwhen true
            endif
            set p = p + 1
        endloop
        if ( not found ) then
            result[i] = udg_ItemArray[i]
        endif
        set i = i + 1
    endloop
    loop
        exitwhen i < 0
        set udg_ItemArray[i] = result[i]
        set i = i - 1
    endloop
    return moved
endfunction
12-26-2003, 08:22 PM#5
weaaddar
Thanks a bunch kattana my algorithim was so horribly messy.
12-29-2003, 11:47 AM#6
KaTTaNa
Did it work? I havn't had time to test it myself. emote_confused
12-30-2003, 05:07 AM#7
weaaddar
Haven't tried it either yet. my trigger comments seem to be disabled by wordledit and it keeps crashing my map. I'm going to try it eventually once I get this damn thing to stop crashing.
01-01-2004, 04:56 AM#8
weaaddar
Hmm Can you help me figure out why doesn't this work? it seems to cause an infinite loop somewhere so war3 doesn't call the next function in the trigger.
This is really bad as I need to rely heavily on the sort function.
Some brief explanation -1 is basically my way of saying theres no item there. getYLim and GetXLim are psuedo dynamicly based on the amount of heroes in the map. And this lets me chose a ridiculous sized inventory if I so chose. (If theres just one hero that means he can have 8192 items in his virtual inventory)
Code:
function getYLim takes nothing returns integer
  local integer i=0
  loop
    exitwhen udg_Hero[i]==null
    set i=i+1
  endloop
  if(i!=0) then
  return(i)
  endif
  return (1)
endfunction
function getXLim takes nothing returns integer
  return 8191/getYLim()
endfunction
function Ix2 takes integer x,integer y returns integer
  return (x*getYlim()+y)
endfunction

function IsBefore takes integer A, integer B returns boolean
    if ( B == -1 ) then
        return true
    endif
    return ( A<B )
endfunction
// Made by KaTTaNa
// modified for ints by weaaddar
function SortVI takes integer heronum returns nothing
    local integer i=0
    local boolean found
    local integer p=0
    local integer q=0
    local integer array result
    loop
       exitwhen i > getXLim()
       set result[i]=-1
       set i=i+1
    endloop
    set i=0
    loop
       exitwhen i>getXLim()
       set found = false
       set p = 0
       loop
         exitwhen p > i
         if (udg_ItemOwned[Ix2(i,heronum)]==-1) then
            exitwhen true
         endif
         if ( IsBefore(udg_ItemOwned[Ix2(i,heronum)], result[p] ) ) then
              set q = i
              loop
                exitwhen q < p
                set result[q+1] = result[q]
                set q = q - 1
              endloop
              set result[p] = udg_ItemOwned[Ix2(i,heronum)]
              set found = true
              exitwhen true
         endif
            set p = p + 1 
       endloop
       if ( not( found ) ) then
           set result[i] = udg_ItemOwned[Ix2(i,heronum)]
       endif
       set i = i + 1
    endloop
    loop
        exitwhen i < 0
        set udg_ItemOwned[Ix2(i,heronum)] = result[i]
        set i = i - 1
    endloop
endfunction
01-01-2004, 11:40 AM#9
KaTTaNa
Store GetXLim() in a local and use that local as reference in your exitwhen statements.
The problem is that GetYLim() loops and it gets called too often. I suggest that you either add another parameter to Ix2 (YLim) so it doesn't call that GetYLim either, or implements it directly in the Sort function.

Something like this:
Code:
function getYLim takes nothing returns integer
  local integer i=0
  loop
    exitwhen udg_Hero[i]==null
    set i=i+1
  endloop
  if(i!=0) then
  return(i)
  endif
  return (1)
endfunction
function getXLim takes nothing returns integer
  return 8191/getYLim()
endfunction

function IsBefore takes integer A, integer B returns boolean
    if ( B == -1 ) then
        return true
    endif
    return ( A<B )
endfunction
// Made by KaTTaNa
// modified for ints by weaaddar
// optimized by KaTTaNa (I think.. :P)
function SortVI takes integer heronum returns nothing
    local integer i=0
    local boolean found
    local integer p=0
    local integer q=0
    local integer array result
    local integer yLim = getYLim()
    local integer xLim = 8191/yLim
    loop
       exitwhen i > xLim
       set result[i]=-1
       set i=i+1
    endloop
    set i=0
    loop
       exitwhen i>xLim
       set found = false
       set p = 0
       loop
         exitwhen p > i
         if (udg_ItemOwned[i*yLim+heronum]==-1) then
            exitwhen true
         endif
         if ( IsBefore(udg_ItemOwned[i*yLim+heronum], result[p] ) ) then
              set q = i
              loop
                exitwhen q < p
                set result[q+1] = result[q]
                set q = q - 1
              endloop
              set result[p] = udg_ItemOwned[i*yLim+heronum]
              set found = true
              exitwhen true
         endif
            set p = p + 1 
       endloop
       if ( not( found ) ) then
           set result[i] = udg_ItemOwned[i*yLim+heronum]
       endif
       set i = i + 1
    endloop
    loop
        exitwhen i < 0
        set udg_ItemOwned[i*yLim+heronum] = result[i]
        set i = i - 1
    endloop
endfunction
01-01-2004, 03:44 PM#10
weaaddar
Alright heres my solutions to this damn thing it works when using a global var though which I'd eventually like to remove.
Code:
function SortVI takes integer y returns nothing
    local integer ylimit=getYLim()
    local integer xlimit=getXLim()
    local integer i=0
    local integer temp
    local integer count=0
    local integer xlim=udg_LastIndex[y]
    local boolean sorted=false
    loop
      exitwhen (sorted)
      set sorted=true
      call BJDebugMsg("The first loop ran")
      set i=0
      loop
         exitwhen (i>xlim)
         if( (udg_ItemOwned[i*ylimit+y] != udg_ItemOwned[(i+1)*ylimit+y]) and ( (udg_ItemOwned[i*ylimit+y]==-1) or ( (udg_ItemOwned[i*ylimit+y] > udg_ItemOwned[(i+1)*ylimit+y] ) and ( udg_ItemOwned[(i+1)*ylimit+y]!=-1 ) ) ) ) then
             set temp=udg_ItemOwned[i*ylimit+y]
             set udg_ItemOwned[i*ylimit+y]=udg_ItemOwned[(i+1)*ylimit+y]
             set udg_ItemOwned[(i+1)*ylimit+y]=temp
             set sorted=false
             exitwhen (true)
         endif                              
         set i=i+1
      endloop
    endloop
    call DisplayTextToForce( GetPlayersAll(), "If the sorting algorithim worked this should be 0:"+I2S(udg_ItemOwned[ Ix2(0,y)] ) )
    set i=0
    loop
       exitwhen i>xlimit
       if (udg_ItemOwned[i*ylimit+y]!=-1) then
          set count=count+1
       endif
       set i=i+1
    endloop
    call DisplayTextToForce( GetPlayersAll(), I2S(count) )
    set udg_LastIndex[y]=count
endfunction