• 🏆 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!

Sorty loops

Status
Not open for further replies.
Level 13
Joined
Nov 7, 2014
Messages
571
Sorty loops

Allow the user to sort "anything" (integer/structs, real, string, handle) with whatever comparison logic that they want.

JASS:
library demo initializer init uses sortyloops

// some print functions so that we can see if the sorting worked;
// they also demonstrate how to access the sorted "things", i.e
// 'operator[]' for integer, real and string, but 'Load*Handle' for handles

private function writeln takes string s returns nothing
    call BJDebugMsg(s)
endfunction

function sl_int_print takes sl_int so returns nothing
    local integer a = 0
    local string s

    if so.end == 0 then
        call writeln("[]")
    endif

    set s = "[" + I2S(so[0])
    set a = 1
    loop
        exitwhen a == so.end
        set s = s + ", " + I2S(so[a])
        set a = a + 1
    endloop
    set s = s + "]"

    call writeln(s)
endfunction

function sl_real_print takes sl_real so returns nothing
    local integer a = 0
    local string s

    if so.end == 0 then
        call writeln("[]")
    endif

    set s = "[" + R2SW(so[0], 1, 3)
    set a = 1
    loop
        exitwhen a == so.end
        set s = s + ", " + R2SW(so[a], 1, 3)
        set a = a + 1
    endloop
    set s = s + "]"

    call writeln(s)
endfunction

function sl_string_print takes sl_string so returns nothing
    local integer a = 0
    local string s

    if so.end == 0 then
        call writeln("[]")
    endif

    set s = "['" + so[0]
    set a = 1
    loop
        exitwhen a == so.end
        set s = s + "', '" + so[a]
        set a = a + 1
    endloop
    set s = s + "']"

    call writeln(s)
endfunction

function sl_unit_print takes sl_handle so returns nothing
    local integer a = 0
    local string s

    if so.end == 0 then
        call writeln("[]")
    endif

    set s = "[" + GetUnitName(LoadUnitHandle(so.ht, 0, 0))
    set a = 1
    loop
        exitwhen a == so.end
        set s = s + ", " + GetUnitName(LoadUnitHandle(so.ht, 0, a))
        set a = a + 1
    endloop
    set s = s + "]"

    call writeln(s)
endfunction


function sl_int_test takes nothing returns nothing
    local sl_int so = sl_int.create()
    local integer a
    local integer cmp

    set a = 0
    loop
        exitwhen a == 10
        call so.add(GetRandomInt(-5, 5))
        set a = a + 1
    endloop

    call sl_int_print(so)

    loop
        exitwhen so.sorted()

        if so[so.index_a] < so[so.index_b] then
            set cmp = -1
        elseif so[so.index_a] > so[so.index_b] then
            set cmp = 1
        else
            set cmp = 0
        endif

        call so.cmp(cmp)
    endloop

    call sl_int_print(so)

    call so.destroy()
endfunction

function sl_real_test takes nothing returns nothing
    local sl_real so = sl_real.create()
    local integer a
    local integer cmp

    set a = 0
    loop
        exitwhen a == 10
        call so.add(GetRandomReal(-100.0, 100.0))
        set a = a + 1
    endloop

    call sl_real_print(so)

    loop
        exitwhen so.sorted()

        if so[so.index_a] < so[so.index_b] then
            set cmp = -1
        elseif so[so.index_a] > so[so.index_b] then
            set cmp = 1
        else
            set cmp = 0
        endif

        call so.cmp(cmp)
    endloop

    call sl_real_print(so)

    call so.destroy()
endfunction

function sl_string_test takes nothing returns nothing
    local sl_string so = sl_string.create()
    local integer a
    local integer cmp
    local integer uid
    local unit u

    set a = 0
    loop
        exitwhen a == 5
        set uid = ChooseRandomCreep(GetRandomInt(0, 10))
        if uid != 0 then
            set u = CreateUnit(Player(0), uid, 0.0, 0.0, 0.0)
            call so.add(GetUnitName(u))
            call RemoveUnit(u)
            set a = a + 1
        endif
    endloop

    call sl_string_print(so)

    loop
        exitwhen so.sorted()

        if StringLength(so[so.index_a]) < StringLength(so[so.index_b]) then
            set cmp = -1
        elseif StringLength(so[so.index_a]) > StringLength(so[so.index_b]) then
            set cmp = 1
        else
            set cmp = 0
        endif

        call so.cmp(cmp)
    endloop

    call sl_string_print(so)

    call so.destroy()
endfunction

function sl_unit_test takes nothing returns nothing
    local sl_handle so = sl_handle.create()
    local integer a
    local integer cmp
    local integer uid
    local player p = Player(0)
    local unit ua
    local unit ub
    local integer ra
    local integer rb

    call so.add(CreateUnit(p, 'opeo', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Ulic', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'ewsp', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Obla', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Udre', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'ugho', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Emoo', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Ofar', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'uaco', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Edem', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'hfoo', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Hpal', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'ogru', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'earc', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'Hblm', 0.0, 0.0, 270.0))
    call so.add(CreateUnit(p, 'hpea', 0.0, 0.0, 270.0))

    call sl_unit_print(so)

    loop
        exitwhen so.sorted()

        set ua = LoadUnitHandle(so.ht, 0, so.index_a)
        set ub = LoadUnitHandle(so.ht, 0, so.index_b)

        // heroes come first, then units
        // also sort by race: human, orc, undead, nightelf
        //
        if IsUnitType(ua, UNIT_TYPE_HERO) and IsUnitType(ub, UNIT_TYPE_HERO) then
            set ra = GetHandleId(GetUnitRace(ua))
            set rb = GetHandleId(GetUnitRace(ub))
            if ra < rb then
                set cmp = -1
            elseif ra > rb then
                set cmp = 1
            else
                set cmp = 0
            endif

        else
            if IsUnitType(ua, UNIT_TYPE_HERO) then
                set cmp = -1
            elseif IsUnitType(ub, UNIT_TYPE_HERO) then
                set cmp = 1
            else
                set ra = GetHandleId(GetUnitRace(ua))
                set rb = GetHandleId(GetUnitRace(ub))
                if ra < rb then
                    set cmp = -1
                elseif ra > rb then
                    set cmp = 1
                else
                    set cmp = 0
                endif
            endif
        endif

        call so.cmp(cmp)
    endloop

    call sl_unit_print(so)

    call so.destroy()
endfunction

private function init takes nothing returns nothing
    // call sl_int_test()
    // call sl_real_test()
    // call sl_string_test()
    call sl_unit_test()
endfunction

endlibrary
 

Attachments

  • sorty-loops.j
    13.7 KB · Views: 43
Status
Not open for further replies.
Top