wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Warcraft III Modding > Developer's Corner > Triggers & Scripts
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 01-06-2010, 10:29 PM   #1
thehellman
User
 
Join Date: Jan 2006
Posts: 158

Submissions (2)

thehellman has little to show at this moment (4)

Default Help With GetRandomUnit()

Collapse JASS:
function GetRandomPlayerHero takes nothing returns unit 
    local integer i = 0
    local unit t    = null
    loop
        set t = PlayerHero[GetRandomInt(0, 7)]
        if( GetUnitAbilityLevel(t, 'A028') > 0 ) then
            set t = null
        endif
    exitwhen t != null
    endloop
    return t
endfunction

I want to be able to get a random unit from an array of units, but only if the unit satisfied the condition (condition being they don't have a certain ability). This is the way I'm doing it now, but it isn't the best way, I'm sure it can be optimized.

I might also add that the array is of size 8, (0-7), and may not always be filled depending on how many players are in the game.
thehellman is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 01-06-2010, 10:57 PM   #2
grim001
requires vJass
 
grim001's Avatar


Code Moderator
 
Join Date: Nov 2006
Posts: 1,540

Submissions (10)

grim001 is just really nice (277)grim001 is just really nice (277)

Send a message via AIM to grim001
Default

Quote:
Originally Posted by thehellman
I might also add that the array is of size 8, (0-7), and may not always be filled depending on how many players are in the game.
The way you are doing it now will probably take the least number of operations on average. Your alternative is to build a local unit array filled with the existent units meeting the critera and use a counter to keep track of how many units you add to it. Then you'd pick a random hero from this new, compact array. The problem is that you would need to loop over this array again and null all the unit references. You'd also have to store the picked unit in a local unit variable before cleaning the array, and since this is what you need to return, the unit variable would need to be a parameter so that it doesn't leak a reference. Then you'd need a wrapper function to hide the null unit parameter. Overall, it'll probably wind up performing worse 99% of the time than your existing function.

It would look something like this:
Expand JASS:

Alternatively, if you instead used an array of pointers to the hero units, you'd have a much easier time since you could avoid using unit references directly:

Expand JASS:

Last edited by grim001 : 01-06-2010 at 11:03 PM.
grim001 is offline   Reply With Quote
Old 01-06-2010, 11:54 PM   #3
weaaddar
User


Respected User
 
Join Date: Apr 2002
Posts: 2,372

Submissions (3)

weaaddar has a spectacular aura about (131)

Default

Grim, that super duper overkill::
Collapse JASS:
function GetRandomPlayerHero takes nothing returns unit 
    local integer i = 0
    local boolean found = false
    loop
        set i = GetRandomInt(0, 7)
        if( GetUnitAbilityLevel(PlayerHero[i], 'A028') == 0 ) then
            set found = true
        endif
    exitwhen found
    endloop
    return PlayerHero[i]
endfunction
weaaddar is offline   Reply With Quote
Old 01-07-2010, 12:26 AM   #4
thehellman
User
 
Join Date: Jan 2006
Posts: 158

Submissions (2)

thehellman has little to show at this moment (4)

Default

Thanks, I think I'll use the second method.

+rep to both.

EDIT: Actually the above function doesn't work. It'll return a null hero, I just added a small null checker.

Last edited by thehellman : 01-07-2010 at 12:36 AM.
thehellman is offline   Reply With Quote
Old 01-07-2010, 02:39 AM   #5
weaaddar
User


Respected User
 
Join Date: Apr 2002
Posts: 2,372

Submissions (3)

weaaddar has a spectacular aura about (131)

Default

The hellman what you should do is instead of making it 0,7 figure out how many players you have and just add there heroes to the array. That way you'd only get null if there are no players without the ability.
weaaddar is offline   Reply With Quote
Old 01-07-2010, 04:30 AM   #6
grim001
requires vJass
 
grim001's Avatar


Code Moderator
 
Join Date: Nov 2006
Posts: 1,540

Submissions (10)

grim001 is just really nice (277)grim001 is just really nice (277)

Send a message via AIM to grim001
Default

Well your function still has a random element, which makes it an upgraded version of the original function. I was just demonstrating what it would look like to remove the random element, but I don't recommend doing it that way since it is overkill and would usually be slower. The fastest way would be to just keep a compact array of eligible heroes and just pick from it with a random integer, and the simplest/preferred method would be what weaaddar posted.
grim001 is offline   Reply With Quote
Old 01-07-2010, 04:36 AM   #7
weaaddar
User


Respected User
 
Join Date: Apr 2002
Posts: 2,372

Submissions (3)

weaaddar has a spectacular aura about (131)

Default

Ah the easiest approach maybe to forgoe the array and just use the BJ function, like GroupPickRandomUnit ofcourse its probably poor for efficiency.
weaaddar is offline   Reply With Quote
Old 01-07-2010, 10:52 AM   #8
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,190

Submissions (19)

Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

You could just use a global array instead of a local one to avoid leaks (you could also use a local integer array that stores the indexes of the PlayerHero array instead of the heroes directly).

This is faster than the looping random checker in cases where only a few players have a valid hero. Most importantly, in the case where there are no valid heroes, this version of the function won't suffer from an infinite loop like the old one, it will just return null.

If such cases are not possible in your game, then it doesn't matter so much which version of the function you use.

Collapse JASS:
globals
    private unit array TempHero
endglobals

function GetRandomPlayerHero takes nothing returns unit 
    local integer i = 0
    local integer j = 0
    loop
        if PlayerHero[i]!=null and GetUnitAbilityLevel(PlayerHero[i], 'A028')==0 then
            set TempHero[j]=PlayerHero[i]
            set j=j+1
        endif
        set i=i+1
        exitwhen i>=8
    endloop
    if j==0 then
        return null
    endif
    set i = GetRandomInt(0, j-1)
    return TempHero[i]
endfunction
__________________
Anitarf is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 01:25 PM.


Affiliates
The Hubb The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services