HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

More Random (question)

02-25-2008, 06:35 PM#1
Pinzu
Can some one direct me a little on this.
I have 10 regions, and 1-10 players...

What I want is a system ( or what ever you call it ) gives all units in one
of these 10 regions to one random player until all players has got one
region. (if the player is in game)

reply, if you dont understand...

and thx for your time.

---
Thx you two! What I really ment was i was out of inspiration on how to confront this problem, but you two inspired me, allthough I don't use that advanced jass, so I did it in GUI...

Now I need a little help to deleak it, or just make it run smoother, any suggestions?

Trigger:
Setup THE SETUP ACTION!!
Collapse Events
Map initialization
Collapse Actions

Set Region_L[1] = L01 <gen>
Set Region_L[2] = L02 <gen>
Set Region_L[3] = L03 <gen>
Set Region_L[4] = L04 <gen>
Set Region_L[5] = L05 <gen>
Set Region_L[6] = L06 <gen>
Set Region_L[7] = L07 <gen>
Set Region_L[8] = L08 <gen>
Set Region_L[9] = L09 <gen>
Set Region_L[10] = L10 <gen>

Trigger:
Randomizing hopefuly...
Events
Conditions
Collapse Actions
Collapse For each (Integer A) from 1 to 10, do (Actions)
Collapse Loop - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
((Player((Integer A))) controller) Equal to User
((Player((Integer A))) slot status) Equal to Is playing
Collapse Then - Actions
Player Group - Add (Player((Integer A))) to Group_pp
Collapse Else - Actions
Do nothing
Collapse For each (Integer A) from 1 to (Number of players in Group_pp), do (Actions)
Collapse Loop - Actions
Collapse Player Group - Pick every player in (Player group((Random player from Group_pp))) and do (Actions)
Collapse Loop - Actions
Collapse Unit Group - Pick every unit in (Units in Region_L[(Integer A)]) and do (Actions)
Collapse Loop - Actions
Unit - Change ownership of (Picked unit) to (Picked player) and Change color
Player Group - Remove (Picked player) from Group_pp

I think what Deaod did, is much about the same, but I dont understand that stuff to well.. :S
PS: normal Jass is accepted...
Good Night! :P
02-25-2008, 08:42 PM#2
Deaod
Collapse JASS:
globals
    rect array ownedunitregions
    rect array playerregions
    integer array playerownedregions
endglobals

function giveregions takes nothing returns nothing
local integer index=0
local integer index2=0
local integer playerplaying=0
local group g=CreateGroup()
local boolexpr b=null
local boolean array rectassigned
    loop
        if GetPlayerSlotState(Player(index))==PLAYER_SLOT_STATE_PLAYING then
            set playerplaying=playerplaying+1
        endif
        set rectassigned[index+1]=false
    set index=index+1
    exitwhen index>9
    endloop

    set index=0

    loop
        set index2=GetRandomInt(1,10)
        if (playerownedregions[index]==0) and (GetPlayerSlotState(Player(index))==PLAYER_SLOT_STATE_PLAYING) and (rectassigned[index2]==false) then
            set playerregions[index]=ownedunitregions[index2]
            set rectassigned[index2]=true
            call GroupEnumUnitsInRect(g, ownedunitregions[index2], b)
            loop
                call SetUnitOwner(FirstOfGroup(g), Player(index), true)
            call GroupRemoveUnit(g, FirstOfGroup(g))
            exitwhen FirstOfGroup(g)==null
            endloop
            set playerownedregions[index]=1
            set playerplaying = playerplaying-1
            call GroupClear(g)
            call DestroyGroup(g)
            set g=CreateGroup()
        endif
    set index=index+1
    exitwhen playerplaying==0
    exitwhen index>9
    endloop
    
    call DestroyGroup(g)
    set g=null
    call DestroyBoolExpr(b)
    set b=null
endfunction
Removed some errors


Ok, this uses Rects instead of Regions, but i didnt know how to do it better. Please note that this code has not been tested and thus may be non-functional.

Deaod
02-25-2008, 11:32 PM#3
Salbrismind
Quote:
Originally Posted by Deaod
Collapse JASS:
globals
    rect array ownedunitregions
    rect array playerregions
    integer array playerownedregions
endglobals

function giveregions takes nothing returns nothing
local integer index=0
local integer index2=0
local integer playerplaying=0
local group g=CreateGroup()
local boolexpr b=null
    loop
        if GetPlayerSlotState(Player(index))==PLAYER_SLOT_STATE_PLAYING then
            set playerplaying=playerplaying+1
        endif
    set index=index+1
    exitwhen index>9
    endloop

    loop
        set index2=GetRandomInt(1,10)
        if (playerownedregions[index]==0) and (GetPlayerSlotState(Player(index))==PLAYER_SLOT_STATE_PLAYING) then
            set playerregions[index]=ownedunitregions[index2]
            call GroupEnumUnitsInRect(g, ownedunitregions[index2], b)
            loop
                call SetUnitOwner(FirstOfGroup(g), Player(index), true)
            call GroupRemoveUnit(g, FirstOfGroup(g))
            exitwhen FirstOfGroup(g)==null
            endloop
            set playerownedregions[index]=1
            set playerplaying = playerplaying-1
            call GroupClear(g)
            call DestroyGroup(g)
            set g=CreateGroup()
        endif
    set index=index+1
    exitwhen playerplaying==0
    exitwhen index>9
    endloop
    
    call DestroyGroup(g)
    set g=null
    call DestroyBoolExpr(b)
    set b=null
endfunction

Ok, this uses Rects instead of Regions, but i didnt know how to do it better. Please note that this code has not been tested and thus may be non-functional.

Deaod

My eyes just stabbed themselves....

There is very likely a much easier way to do this. In gui I would make 2 triggers. One would be the main trigger and it could be a larger one with many other things inside not just the code for this thing you want to do. The second trigger is your backup incase one of the ifs gets a false reading.

In the first trigger make a for loop from 1 - 10 then inside it randomize a number from one to ten and use that number to choose which player goes to that region. After the randomizing number has a if to check if that player already has units. To check for that make sure you have an array of 10 booleans, and when a player gets a region then set there corresponding boolean to true. If the "if" returns false have the game start up your second trigger. Inside the second trigger are the same actions as the first except that it does not have a for loop. In the else part of the if put an action to restart the trigger. Thus the second will continue until you find a player that doesn't have a region.

The final thing to do is make sure that in the first trigger, right before the randomizing number you put the action : Wait for boolean to be true (or w/e its name is) and use it to control the for loop to ensure it does not go until you have the player for that region.

Code:
Trigger:
Choose Region
Collapse Events
Time - Elapsed game time is 5.00 seconds
Conditions
Collapse Actions
Collapse For each (Integer A) from 1 to 10, do (Actions)
Collapse Loop - Actions
Wait until (Scdtrig Equal to False), checking every 0.10 seconds
Set playernum = (Random integer number between 1 and 10)
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
playregs[playernum] Equal to True
Collapse Then - Actions
Set Scdtrig = True
Trigger - Run Region Backup <gen> (ignoring conditions)
Collapse Else - Actions
Set playregs[playernum] = True
-------- (Anything Else You want to do) --------

Trigger:
Region Backup
Events
Conditions
Collapse Actions
Set playernum = (Random integer number between 1 and 10)
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
playregs[playernum] Equal to True
Collapse Then - Actions
Trigger - Run (This trigger) (ignoring conditions)
Collapse Else - Actions
Set playregs[playernum] = True
-------- (Anything Else You want to do) --------
02-26-2008, 03:52 PM#4
Deaod
i noticed a small error. "index" needs to be resetted to zero after the first loop.
and the same rect could be assigned to a player twice. Going to correct that.

i did not really use vJASS. Only the globals block, but thats not a real problem; just create those variables in GUI and rename the variables in the code i posted to "udg_"+variablename.
02-26-2008, 04:50 PM#5
Strilanc
There is a well known algorithm for permuting a list, and here it is in JASS:

Collapse JASS:
///may have incorrect function names, but you get the idea
function permuteRegions takes nothing returns nothing
  local integer j
  local integer i = 1
  local rect r
  //for each region
  loop
    exitwhen i > num_regions
    //swap with a random region not behind this region in the list
    set j = RandomInteger(i, numRegions)
    set r = regions[i]
    set regions[i] = regions[j]
    set regions[j] = r
    set i = i + 1
  endloop
endfunction

That will randomize the list of regions, then you just give the nth player the region in the nth slot.
02-26-2008, 08:06 PM#6
Pinzu
Thx all of you, really helpful, while we are at it...

can I make a loop go from playernumber to 10 and then continue the loop from 1 to player number, some thing like that. I really need it.

X --> 10, 1 --> X


uhh, I almost forgot.. whats the code to get a units gold cost?
02-26-2008, 09:12 PM#7
Deaod
Collapse JASS:
function playernumberloop takes integer playernumber returns nothing
local integer index=playernumber
    loop
        if index=10 then
            set index=0
        endif
        //do your stuff...
        set index=index+1
        exitwhen index=playernumber
    endloop
endfunction
Ok, you have to remember this function starts counting at zero (Player(0) = Player red/one)

as for your second question: i haven't found any native or BJ function for you to do this. But you can set the point value of the unit to the gold cost and use GetUnitPointValueByType(...) or GetUnitPointValue(...). That should do it.
02-26-2008, 09:23 PM#8
Pinzu
Quote:
...But you can set the point value of the unit to the gold cost and use GetUnitPointValueByType(...) or GetUnitPointValue(...). That should do it.

I did use that befor, but I tought there was a other way :/