• 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.

High to Low Sorter v 1.0.2.5

This sorts a ton of different things from high to low. Look at the code trigger for explanation on how to use and the function list.
This is GUI friendly and the demo code in the map is in GUI.

This requires Bribes unit Indexer or for the units to have different custom values. ( for most of the functions)

Thanks to Maker for showing me how to make a high to low sorter a long time ago.

  • HighToLowSorterVariables
    • Events
    • Conditions
    • Actions
      • Set h2LGlobalInt1[0] = 0
      • Set h2LGlobalInt2[0] = 0
      • Set h2LGlobalReal[0] = 0.00
      • Set h2LMaxValue = 0
      • Set h2LMinValue = 0
      • Set h2LReturnedPlacementH2L[0] = 0
      • Set h2LSorterIntegerArray[0] = 0
      • Set h2LSorterRealArray[0] = 0.00
      • Set h2LSorterUnitArray[0] = No unit
JASS:
    // High to low sorter Template by deathismyfriend
    // Thanks to Maker for showing me how to do these.
    // version 1.0.2.5
    
    //                   FUNCTION LIST
    //
    //
    //                   THIS IS HOW TO USE EVERY FUNCTION
    // Example on how to use.
    // Put the units into the unit array.  h2LSorterUnitArray[ key]
    // Then set the minimum value to the min key value.
    // Then set the maximum value to the max key value.
    // call the function you want using the custom script.
    // Then the values will be sorted from high to low. You can use these values by using the integer stored in the integer array.
    // H2LReturnedPlacementH2L[ key] 
    // the key is the units custom value. The value loaded is an integer value telling the place of the unit. 
    //
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST CUSTOM VALUE
    // This function returns high to low values based on which unit has the highest custom value.
    // Custom script: call H2LCustomValueSorter()
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST STATS
    // This function returns high to low values based on which unit has the highest stats.
    // // Example: Agi + Str + Intel
    // Custom script: call H2LStatsSorter( boolean)
    // The boolean tells whether or not you want to include bonus stats.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST AGILITY
    // This function returns high to low values based on which unit has the highest Agi.
    // Custom script: call H2LAgiSorter( boolean)
    // The boolean tells whether or not you want to include bonus stats.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST INTELIGENCE
    // This function returns high to low values based on which unit has the highest Agi.
    // Custom script: call H2LIntSorter( boolean)
    // The boolean tells whether or not you want to include bonus stats.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST STRENGTH
    // This function returns high to low values based on which unit has the highest Str.
    // Custom script: call H2LStrSorter( boolean)
    // The boolean tells whether or not you want to include bonus stats.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST LEVEL
    // This function returns high to low values based on which unit has the highest level.
    // Custom script: call H2LLevelSorter()
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST REMAINING / MAX HEALTH
    // This function returns high to low values based on which unit has the highest remaining / max health.
    // Custom script: call H2LHealthSorter( boolean)
    // The boolean tells whether or not you want to compare max health or remaining health.
    // True means remaining health
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST REMAINING / MAX MANA
    // This function returns high to low values based on which unit has the highest remaining / max mana.
    // Custom script: call H2LManaSorter( boolean)
    // The boolean tells whether or not you want to compare max mana or remaining mana.
    // True means remaining mana
    //
    //
    //                   HIGH TO LOW SORTER BASED ON HIGHEST REMAINING / MAX MANA AND / OR HEALTH
    // This function returns high to low values based on which unit has the highest remaining / max mana and / or health.
    // Custom script: call H2LHealthManaSorter( boolean, boolean)
    // The first boolean tells whether or not you want to compare max health or remaining health.
    // True means remaining health.
    // The second boolean tells whether or not you want to compare max mana or remaining mana.
    // True means remaining mana.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON INTEGERS MUI
    // This function returns high to low values based on which unit has the highest integer.
    // By highest integer this is specialized stats like kills / deaths / score / damage done by unit / whatever else you can think of.
    // Custom script: call H2LIntegerMUISorter()
    // The integer values for kills or whatever you want needs to be stored into the h2LSorterIntegerArray variable.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON INTEGERS MPI
    // This function returns high to low values based on which player has the highest integer.
    // This is for displaying which player has the highest.
    // By highest integer this is specialized stats like kills / deaths / score / damage done by player / whatever else you can think of.
    // Custom script: call H2LIntegerMPISorter()
    // The integer values for kills or whatever you want needs to be stored into the h2LSorterIntegerArray variable.
    // The integer for players will be taken from the key. This means that you should store the things for player one red into the right keyed variable.
    // // Example: h2LSorterIntegerArray[ 1] = score       and so on. You can use player number of player also.
    // For this make sure the min value is one unless player 1 does not exist in your game.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON REALS MUI
    // This function returns high to low values based on which unit has the highest integer.
    // By highest integer this is specialized stats like damage done by unit / damage done to a unit / whatever else you can think of.
    // Custom script: call H2LRealMUISorter()
    // The integer values for kills or whatever you want needs to be stored into the h2LSorterRealArray variable.
    //
    //
    //                   HIGH TO LOW SORTER BASED ON REALS MPI
    // This function returns high to low values based on which player has the highest integer.
    // This is for displaying which player has the highest.
    // By highest integer this is specialized stats like damage done by player / damage dont to a player / whatever else you can think of.
    // Custom script: call H2LRealMPISorter()
    // The integer values for kills or whatever you want needs to be stored into the h2LSorterRealArray variable.
    // The integer for players will be taken from the key. This means that you should store the things for player one red into the right keyed variable.
    // // Example: h2LSorterRealArray[ 1] = score       and so on. You can use player number of player also.
    // For this make sure the min value is one unless player 1 does not exist in your game.
    //
    //
    
    function H2LSortingFunction1 takes nothing returns nothing
        //it is easier to read with locals
        local integer start = udg_h2LMinValue
        local integer curr = start + 1
        local integer end = udg_h2LMaxValue
        local integer temp
        local integer L = start
        
        // This loop sorts those integers in order from highest to lowest.
        loop
            if udg_h2LGlobalInt1[ start] < udg_h2LGlobalInt1[ curr] then
                set temp = udg_h2LGlobalInt1[ start]
                set udg_h2LGlobalInt1[ start] = udg_h2LGlobalInt1[ curr]
                set udg_h2LGlobalInt1[ curr] = temp
            endif
            exitwhen start == end - 1
            if curr == end then
                set curr = start + 2
                set start = start + 1
            else
                set curr = curr + 1
            endif
        endloop
        
        // This loop returns the units placement in an array keyed to that units custom value.
        loop
            exitwhen L > end
            set udg_h2LReturnedPlacementH2L[ udg_h2LGlobalInt1[ L]] = L
            set L = L + 1
        endloop
    endfunction
    
    function H2LSortingFunction2 takes nothing returns nothing
        //it is easier to read with locals
        local integer start = udg_h2LMinValue
        local integer curr = start + 1
        local integer end = udg_h2LMaxValue
        local integer temp1
        local integer temp2
        local integer L = start
        
        // This loop sorts those integers in order from highest to lowest.
        loop
            if udg_h2LGlobalInt2[ start] < udg_h2LGlobalInt2[ curr] then
                set temp1 = udg_h2LGlobalInt1[ start]
                set temp2 = udg_h2LGlobalInt2[ start]
                set udg_h2LGlobalInt1[ start] = udg_h2LGlobalInt1[ curr]
                set udg_h2LGlobalInt2[ start] = udg_h2LGlobalInt2[ curr]
                set udg_h2LGlobalInt1[ curr] = temp1
                set udg_h2LGlobalInt2[ curr] = temp2
            endif
            exitwhen start == end - 1
            if curr == end then
                set curr = start + 2
                set start = start + 1
            else
                set curr = curr + 1
            endif
        endloop
        
        // This loop returns the units placement in an array keyed to that units custom value.
        loop
            exitwhen L > end
            set udg_h2LReturnedPlacementH2L[ udg_h2LGlobalInt1[ L]] = L
            set L = L + 1
        endloop
    endfunction
    
    function H2LSortingFunction3 takes nothing returns nothing
        //it is easier to read with locals
        local integer start = udg_h2LMinValue
        local integer curr = start + 1
        local integer end = udg_h2LMaxValue
        local integer temp1
        local real temp2
        local integer L = start
        
        // This loop sorts those integers in order from highest to lowest.
        loop
            if udg_h2LGlobalReal[ start] < udg_h2LGlobalReal[ curr] then
                set temp1 = udg_h2LGlobalInt1[ start]
                set temp2 = udg_h2LGlobalReal[ start]
                set udg_h2LGlobalInt1[ start] = udg_h2LGlobalInt1[ curr]
                set udg_h2LGlobalReal[ start] = udg_h2LGlobalReal[ curr]
                set udg_h2LGlobalInt1[ curr] = temp1
                set udg_h2LGlobalReal[ curr] = temp2
            endif
            exitwhen start == end - 1
            if curr == end then
                set curr = start + 2
                set start = start + 1
            else
                set curr = curr + 1
            endif
        endloop
        
        // This loop returns the units placement in an array keyed to that units custom value.
        loop
            exitwhen L > end
            set udg_h2LReturnedPlacementH2L[ udg_h2LGlobalInt1[ L]] = L
            set L = L + 1
        endloop
    endfunction
    
    function H2LCustomValueSorter takes nothing returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the units custom values into an array.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set L = L + 1
        endloop
        
        call H2LSortingFunction1()
    endfunction
    
    function H2LStatsSorter takes boolean bonuses returns nothing
        local integer L = udg_h2LMinValue
        local unit u // This is here because it is easier to read rather than with the huge unit name
        
        // this loop places the units custom values into an array.
        loop
            exitwhen L > udg_h2LMaxValue
            set u = udg_h2LSorterUnitArray[ L]
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( u)
            set udg_h2LGlobalInt2[ L] = GetHeroAgi( u,bonuses) + GetHeroInt( u,bonuses) + GetHeroStr( u,bonuses)
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
        set u = null
    endfunction
    
    function H2LAgiSorter takes boolean bonuses returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the units custom values into an array.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set udg_h2LGlobalInt2[ L] = GetHeroAgi( udg_h2LSorterUnitArray[ L], bonuses)
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
    endfunction
    
    function H2LIntSorter takes boolean bonuses returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the units custom values into an array.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set udg_h2LGlobalInt2[ L] = GetHeroInt( udg_h2LSorterUnitArray[ L], bonuses)
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
    endfunction
    
    function H2LStrSorter takes boolean bonuses returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the units custom values into an array.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set udg_h2LGlobalInt2[ L] = GetHeroStr( udg_h2LSorterUnitArray[ L], bonuses)
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
    endfunction
    
    function H2LLevelSorter takes nothing returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the units custom values into an array.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set udg_h2LGlobalInt2[ L] = GetHeroLevel( udg_h2LSorterUnitArray[ L])
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
    endfunction
    
    function H2LHealthSorter takes boolean remaining returns nothing
        local integer L = udg_h2LMinValue
        
        if remaining then
            // this loop places the units custom values into an array using the units remaining health.
            loop
                exitwhen L > udg_h2LMaxValue
                set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
                set udg_h2LGlobalReal[ L] = GetWidgetLife( udg_h2LSorterUnitArray[ L])
                set L = L + 1
            endloop
        else
            // this loop places the units custom values into an array using the units remaining health
            loop
                exitwhen L > udg_h2LMaxValue
                set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
                set udg_h2LGlobalReal[ L] = GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MAX_LIFE)
                set L = L + 1
            endloop
        endif
        
        call H2LSortingFunction3()
    endfunction
    
    function H2LManaSorter takes boolean remaining returns nothing
        local integer L = udg_h2LMinValue
        
        if remaining then
            // this loop places the units custom values into an array using the units remaining health.
            loop
                exitwhen L > udg_h2LMaxValue
                set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
                set udg_h2LGlobalReal[ L] = GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MANA)
                set L = L + 1
            endloop
        else
            // this loop places the units custom values into an array using the units remaining health
            loop
                exitwhen L > udg_h2LMaxValue
                set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
                set udg_h2LGlobalReal[ L] = GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MAX_MANA)
                set L = L + 1
            endloop
        endif
        
        call H2LSortingFunction3()
    endfunction
    
    function H2LHealthManaSorter takes boolean remHealth, boolean remMana returns nothing
        local integer L = udg_h2LMinValue
        
        if remHealth then
            // this loop places the units custom values into an array using the units remaining health.
            loop
                exitwhen L > udg_h2LMaxValue
                set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
                set udg_h2LGlobalReal[ L] = GetWidgetLife( udg_h2LSorterUnitArray[ L])
                if remMana then
                    set udg_h2LGlobalReal[ L] = udg_h2LGlobalReal[ L] + GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MANA)
                else
                    set udg_h2LGlobalReal[ L] = udg_h2LGlobalReal[ L] + GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MAX_MANA)
                endif
                set L = L + 1
            endloop
        else
            // this loop places the units custom values into an array using the units remaining health
            loop
                exitwhen L > udg_h2LMaxValue
                set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
                set udg_h2LGlobalReal[ L] = GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MAX_LIFE)
                if remMana then
                    set udg_h2LGlobalReal[ L] = udg_h2LGlobalReal[ L] + GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MANA)
                else
                    set udg_h2LGlobalReal[ L] = udg_h2LGlobalReal[ L] + GetUnitState( udg_h2LSorterUnitArray[ L], UNIT_STATE_MAX_MANA)
                endif
                set L = L + 1
            endloop
        endif
        
        call H2LSortingFunction3()
    endfunction
    
    function H2LIntegerMUISorter takes nothing returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the integers passed into the stats integer array and the custom value into i.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set udg_h2LGlobalInt2[ L] = udg_h2LSorterIntegerArray[ L]
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
    endfunction
    
    function H2LIntegerMPISorter takes nothing returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the integers passed into the stats integer array and the custom value into i.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = L
            set udg_h2LGlobalInt2[ L] = udg_h2LSorterIntegerArray[ L]
            set L = L + 1
        endloop
        
        call H2LSortingFunction2()
    endfunction
    
    function H2LRealMUISorter takes nothing returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the integers passed into the stats integer array and the custom value into i.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = GetUnitUserData( udg_h2LSorterUnitArray[ L])
            set udg_h2LGlobalReal[ L] = udg_h2LSorterRealArray[ L]
            set L = L + 1
        endloop
        
        call H2LSortingFunction3()
    endfunction
    
    function H2LRealMPISorter takes nothing returns nothing
        local integer L = udg_h2LMinValue
        
        // this loop places the integers passed into the stats integer array and the custom value into i.
        loop
            exitwhen L > udg_h2LMaxValue
            set udg_h2LGlobalInt1[ L] = L
            set udg_h2LGlobalReal[ L] = udg_h2LSorterRealArray[ L]
            set L = L + 1
        endloop
        
        call H2LSortingFunction3()
    endfunction
    
    function InitTrig_HighToLowSorterCode takes nothing returns nothing
    endfunction


version 1.0.2.5
Added more functions.
Made things more efficient.
Uses a few more variables.​
version 1.0.2.0
Added in 2 more options for sorting.
This adds the ability to tell scores from high to low based on many other things you want.
Examples: based on units kill / units deaths / units score / damage done to unit / damage unit did to others / players scores / player kills / player deaths / damage players did to others / damage players have taken / and whatever else you can think of.​
version 1.0.1.1
Fixed so that people using normal WE can use this now.​
version 1.0.1.0
Upadted to include a sorter for highest stats( agi/intel/str) / agility / inteligence / strength / health / level / mana / health + mana /
remaining health / remaining mana / remaining health + mana​
version 1.0.0.0
First version released​


Keywords:
high to low sorter, h2l, high to low, custom value, deathismyfriend, dimf
Contents

Template Map (Map)

Reviews
11:57, 22nd Nov 2013 Purgeandfire: Approved. still uses bubble sort, but it is functional.

Moderator

M

Moderator

11:57, 22nd Nov 2013
Purgeandfire: Approved. still uses bubble sort, but it is functional.
 
By slow, Almia meant that the algorithm is slow. This is a simple bubble sort. You can achieve better complexity with a different algorithm. For example:

Wikipedia said:
Bubble Sort
Worst case performance O(n^2)
Best case performance O(n)
Average case performance O(n^2)

QuickSort
Worst case performance O(n2) (extremely rare)
Best case performance O(n log n)
Average case performance O(n log n)

Bubble sort is not that bad for small sets of data (e.g. 10-20), but something like QuickSort is almost always better. Merge sort is often even better, but it can have an ugly implementation in JASS.

P.S. You have a decent amount of repeated code with the loops. You might want to move it to a separate function.
 
Level 16
Joined
Aug 7, 2009
Messages
1,406
I learned this from maker. I have never done any algorithm work before if you could show me the quicksort i can implement it.

http://en.wikipedia.org/wiki/Quicksort

You could also go with Shellsort (or Shell-sort, as you'd translate from Hungarian - we used that name):

http://en.wikipedia.org/wiki/Shellsort

It shouldn't look that bad when implemented in JASS.

----

Bubble sort isn't actually all that bad for low amount of data, but you should use the "corrected" algorithm - the one that memorizes where the last swap takes places and continues from that point in the next iteration. More ("Optimizing bubble sort"):

http://en.wikipedia.org/wiki/Bubble_sort
 
http://en.wikipedia.org/wiki/Quicksort

You could also go with Shellsort (or Shell-sort, as you'd translate from Hungarian - we used that name):

http://en.wikipedia.org/wiki/Shellsort

It shouldn't look that bad when implemented in JASS.

----

Bubble sort isn't actually all that bad for low amount of data, but you should use the "corrected" algorithm - the one that memorizes where the last swap takes places and continues from that point in the next iteration. More ("Optimizing bubble sort"):

http://en.wikipedia.org/wiki/Bubble_sort

Yes after he told me the names i looked on wiki for info problem is all the stuff is in c / c++ and i can't read that.
 
Level 16
Joined
Aug 7, 2009
Messages
1,406
The pseudo version is there everywhere, so it shouldn't be a problem (as its whole purpose is to explain the algorithm without limiting it to a specific programming language):) Yea, I know, at first sight they look like a monster, but the theory behind them is really simple (as always - the most efficient algorithms are usually based on the simplest ideas). You just need to sit down and go through the code once, you'll understand it easily.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Insertion sort is simple and easy to understand, and wikipedia says it's better than bubble sort.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
I knew that, but I did the one with optimization. I'll try if I could do the Insertion sort one. Regardless, sorry.
 
Level 22
Joined
Sep 24, 2005
Messages
4,821

Sorting Algorithm
Worst case performanceAverage case performanceBest case performanceWorst case space complexity
MergesortO(n log n)O(n log n)O(n log n) typical;O(n) natural variantO(n) auxiliary
QuicksortO(n2) Extremely RareO(n log n)O(n log n)O(n) auxiliary; O(log n) auxiliary (Sedgewick 1978)

From wikipedia. My guess is mergesort, basing from the worst case performance, but that's bad analysis on my part, you really should do research on this.
 
QuickSort is typically the fastest sort, hence why it's called quicksort. However, it's an unstable sort, giving it a wider range of possibilities (like the O(n^2)).

Merge Sort is a stable sort

I know quicksort has a small percent chance to be worst case. Which one would you suggest that i use ?
I'm siding with quicksort atm but i don't know a lot about programming and i know you do.

@chobibo
thanks
 
Top