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

Simple for loop in VJASS?

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,338
Hi,

Is there a shorthand syntax for a simple for loop in VJASS? Instead of writing out loop with a counter, we could do a simple for loop syntax. I can't imagine it would be that much of a problem to simply translate this syntax into the actual loop structure JASS requires.

It would be nice if we could have 2 for loop syntax:

JASS:
//the exit_condition is a boolean expression which when true will exit the for loop
//some_expression is a calculation that is performed at the end of each loop
//it should be optional
for integer i = value, exit_condition , some_expression:
  statements
endfor

which would just translate to

JASS:
set local integer i = value
loop
  exitwhen exit_condition //boolean expression evaluates to true
  statements
  ...
  some_expression //could simply increment i or something fancier
endloop

another shorthand for loop would be nice too for just iterating over elements in an array

JASS:
for element in myArray: //in the body we can use the name "element" or whatever to reference the ith member of the array
  statements
  ...
endfor

which again would just be translated to

JASS:
set local integer i = 0
local SomeType current_element
loop
  exitwhen i == len(myArray)
  set current_element = myArray[i]
  statements
  ...
  set i = i + 1
endloop

It would make (at least from my point of view) the code higher level and easier to read.
 
Cohadar's jasshelper supports it:
JASS:
// while unit has some buff do some healing
while GetUnitAbilityLevel(whichUnit, 'Bhea') > 0
    call SetWidgetLife(whichUnit, GetWidgetLife(whichUnit) + 10.)
    call TriggerSleepAction(0.1)
endwhile
 
// print out numbers from 1 to 10 with for loop
for i = 1 to 10
    call BJDebugMsg(I2S(i))
endfor
 
// print only 1 2 3
for i = 1 to 10
    call BJDebugMsg(I2S(i))
    if i == 3 then
        break
    endif
endfor
 
// print out numbers from 10 downto 1
for i = 10 downto 1
    call BJDebugMsg(I2S(i))
endfor
 
// kill all units in a group
for enumUnit in someGroup
    call KillUnit(enumUnit)
endfor
// WARNING: groups are empty after for loop

Taken from this post:
http://blizzardmodding.info/4263/the-jass-newgen-pack-jngp-2-0/

Although, I wouldn't recommend it for systems since most systems still rely on vex jasshelper's order of things. For personal use it is fine though.

Actually, tbh zinc is probably the best for you since jasshelper inherently supports it. If you just want it as a feature for vJASS, then you can use cohadar's jasshelper. To do that, just go to the JASSHelper menu and then tick "Enable Cohadar's jasshelper". That feature should be there for version 5e and 2.0+ (moyack's releases).

EDIT: I don't think anyone implemented the second case (maybe wurstscript has it?). It is a bit of a double-edged sword to implement syntactic sugar in vJASS. You don't know the array sizes (unlike standard programming languages), and you often end up with a lot of code bloat to make it work.
 
Well what about the second case, where I don't want the index, just each member of the array in order?

arrays in JASS aren't like C arrays. They are like java ArrayLists. They're dynamically resized and there is no way in plain JASS to tell if an array has a static size, so by extension, zinc can't tell either.
 
Well what about the second case, where I don't want the index, just each member of the array in order?

If you're talking about foreach then no there's no native way to do that.

Remember everything is just compiled to JASS. Sure foreach could be simulated, but you might as well do it yourself with for.

JASS:
//! zinc
    library Example
    {
        function onInit()
        {
            integer i = 0;
            string list[];
            list[0] = "Hello";
            list[1] = " ";
            list[2] = "World!";
            for ( 0 <= i < 2)
                BJDebugMsg(list[i]);
        }

    }
//! endzinc
Of course you would have to make sure the array doesn't have null entries on your own.

Also why wouldn't this functionality be put into VJASS by default?

I think Vex felt these were just cosmetic things and wanted to stick as close to JASS as possible. Although I would have liked different loops implemented as well.

It may also have something to do with JASS not being able to support proper ++/-- operators.
 
Level 8
Joined
Nov 20, 2011
Messages
202
Wurst also supports other kinds of for loops:

JASS:
for int i = 1 to 10
for int i = 1 to 10 step 2
for int i = 10 downto 1
for int i = 10 downto 1 step 2
for int i = 'xyza' to 'xyzg'

for unit u in group
for unit u from group (will remove the units from the group)
for player p in force
for MyClass c in some List/Queue/Stack/Or some other custom datastructure

For more information take a look at this: http://peq.github.io/WurstScript/manual.html#loops
 
Status
Not open for further replies.
Top