Uncertainty how "return" works

afisakov

You can change this now in User CP.
Reaction score
37
I am working on a trigger that picks a random unit to train, and I need it to not be the same as the last one trained.
the full trigger action
Code:
function Trig_Random_Actions takes nothing returns nothing
  local integer Random
  local integer i = 1
  local integer iEnd = 10
  local group TempGroup
  set Random = GetRandomInt(1,10)
if Random == udg_prevc then
call Trig_Random_Actions()
return
endif
  set TempGroup = GetUnitsOfPlayerAndTypeId(GetTriggerPlayer(), 'hhou')
  if (CountUnitsInGroup(TempGroup) == 1 ) then
  call IssueTrainOrderByIdBJ( GroupPickRandomUnit(TempGroup), udg_Governors[Random] )
  call AdjustPlayerStateBJ( (60/udg_Player_Count) , GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD )
  endif
  call DestroyGroup( TempGroup )
  set TempGroup = null
set udg_prevc=Random
endfunction
the part that SHOULD solve my problem
note: Trig_Random_Actions()=name of this trigger
Code:
if Random == udg_prevc then
call Trig_Random_Actions()
return
endif
What it should do is rerun the trigger, and thus re-random the integer, any time the random integer matches the previous successful result, and that "return" will stop the rest of the trigger from running.
I did not just re-random the integer because then there is a chance it will give same result again and I would be stuck with it.
1) Will this work in guaranteeing second random is different from first
2) are here any problems with this approach I am not seeing (potential glitches, leaks etc.) or just a more elegant/efficient way of doing this?

Thank you in advance for your assistance
 
Last edited by a moderator:

tom_mai78101

The Helper Connoisseur / Ex-MineCraft Host
Staff member
Reaction score
1,633
Fixed your trigger codes for you.
Code:
Please use these tags when posting full JASS triggers:
[CODE]

If you want to hide the codes (for not taking up too much space), wrap it around with [ SPOILER] tags.

You should try and keep an array of all trainable units, or have some attributes added to the units that you can keep track of at any time.

If the trigger picks out a unit, you need to mark that unit as "training" or set a boolean flag for it. That way, if the trigger were to re-pick a random unit, it will first check to see if the boolean flag has been set (the attribute checking), and then pick appropriately.

----------------

As to answer your uncertainty regarding "return":

Code:
function syntax_Example_Sum takes integer i, real r returns real //function declaration must include: the keyword "function",
                                                                  //the function name, parameters (if any) and return type (if
                                                                  //it returns something)
   return i + r //return statements must begin with the keyword "return"
endfunction
 

afisakov

You can change this now in User CP.
Reaction score
37
My attempt to fix it using array instead
prev_trained is a boolean array of size 10.
Code:
function Trig_Random_Conditions takes nothing returns boolean
  return (CountUnitsInGroup(GetUnitsOfPlayerAndTypeId(GetTriggerPlayer(), 'hhou')) == 1 )
endfunction

function Trig_Random_Actions takes nothing returns nothing
  local integer Random
  local integer iEnd = 10
  local group TempGroup
   loop
     set Random = GetRandomInt(1,iEnd)
     exitwhen udg_prev_trained[Random]==false
   endloop
  set TempGroup = GetUnitsOfPlayerAndTypeId(GetTriggerPlayer(), 'hhou')
  if (CountUnitsInGroup(TempGroup) == 1 ) then
  call IssueTrainOrderByIdBJ( GroupPickRandomUnit(TempGroup), udg_Governors[Random] )
  call AdjustPlayerStateBJ( (60/udg_Player_Count) , GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD )
  endif
  call DestroyGroup( TempGroup )
  set TempGroup = null
set udg_prev_trained[Random]=true
endfunction

//===========================================================================
function InitTrig_Random takes nothing returns nothing
  set gg_trg_Random = CreateTrigger(  )
  call TriggerRegisterPlayerChatEvent( gg_trg_Random, Player(0), "-random", true )
  call TriggerRegisterPlayerChatEvent( gg_trg_Random, Player(1), "-random", true )
  call TriggerRegisterPlayerChatEvent( gg_trg_Random, Player(2), "-random", true )
  call TriggerRegisterPlayerChatEvent( gg_trg_Random, Player(3), "-random", true )
//  call TriggerAddCondition( gg_trg_Random, Condition( function Trig_Random_Conditions ) )
  call TriggerAddAction( gg_trg_Random, function Trig_Random_Actions )
endfunction

Key change
Code:
   loop
     set Random = GetRandomInt(1,iEnd)
     exitwhen udg_prev_trained[Random]==false
   endloop
...
set udg_prev_trained[Random]=true
Hopefully this will re-random as many times as needed to get a new choice, thanks to the loop.

P.S. Would the "return" method have worked? Hard to test since only 1 builder allowed per player, and thus identical randoms only occur on multiplayer.
 

tom_mai78101

The Helper Connoisseur / Ex-MineCraft Host
Staff member
Reaction score
1,633
Maybe you can return an object via functions instead?

EDIT:

To test your "return", you can try creating a unit JASS test case. What it means is that you recreate a very small working prototype function in a new map, so that when you call that function, it does what you wanted.

To test for multiplayer, see if you can randomized random seeds each time a unit was picked.
 

jonas

You can change this now in User CP.
Reaction score
64
or do this:

JASS:
set Random = GetRandomInt(1,9) // note 9...
if Random == udg_prevc then
  set Random = 10
endif


(after initializing udg_prevc to GetRandomInt(1,10))

Yes, I believe the return method would have worked. It would have been slower, since function calls and returns are more expensive than loop iterations.
However, this is irrelevant for your example.
Furthermore, download the newest jasspack newgen, which has the ability to run multiple instances of Wc3 in parallel. Then you can test multiplayer.
In addition to this, you can always test your method by using a different map and modifying the script so that it would, e.g., create 10 units for the same player according to this method.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top