God I need a repeat until...

  • Pseudo code:

    Repeat
     Found = FALSE
     X=Time mod 10
     if X = 0 then Found = TRUE
    Until Found = True
    
  • Does the stop loop action work?

  • Does the stop loop action work?

    I imagine it would but, both For and Repeat in Construct force you to enter a number of times it should be repeated. Seems like bad coding to add in a for loop to run a million times just to make sure you get the job done when a repeat until a boolean condition exists would work.

    While is totally unsuitable, at least in my coding experience, because the instant 'Found' becomes true, it breaks the loop.

    But yea, thanks for the idea. I guess a million for loop is on the way.

  • lol, yea, crashed the editor to the point that I got an Aww Snap trying that stunt. Lost about 4 hours of work.

  • Instead of the repeat you could use an infinite while with a condition at the end to stop the loop. Isn’t that the same as a do..while?

    While

    — do stuff

    — system:compare found=1

    ——stop loop

  • Well be damned.

    In every other language the While requires a condition.

    While found=false do begin
     do stuff
    end while
    

    In that case, even a single found=true breaks the while loop.

    Apparently Construct doesn't even require a condition for the while. Never needed one before so that was a bit unexpected.

    Thanks.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • You could just use a variable.

  • Sounds equivalent to a do...while loop. I can't say I really use them myself, I don't find it that common that I want to execute at least 1 pass of the block before checking the condition. In fact the example you gave works fine without. I wrote up a few variants based on the example you gave:

    let found = false;
    do {
     const x = time() % 10;
     if (x == 0)
     	found = true;
    }
    while (found == false)
    

    Fairly simple usage of the do...while loop in JS, uses a variable external to the statement to keep track of the "found" state. Can loop forever.

    while (true) {
     const x = time() % 10;
     if (x == 0)
     	break;
    }
    

    Infinite while loop with a break when the condition is met, simple and easy to read. Can loop forever.

    let repeats = 10;
    while (repeats-- > 0) {
     const x = time() % 10;
     if (x == 0)
     	break;
    }
    

    Same as before but will only repeat a certain number of times, so it won't loop forever.

    let found = false;
    while (found == false) {
     const x = time() % 10;
     if (x == 0)
     	found = true;
    }
    

    Just a normal while loop instead of a do...while, works exactly the same in this example.

    loop {
     let x = time() % 10;
     if (x == 0)
     	break;
    }
    

    Special mention here, the Rust language actually has a "loop" statement, while is basically the same as while (true) {}. Functionally identical, and easy replaced with a normal while loop. But I find the simplicity of it pleasant, something about putting "true" as the condition for a while loop has always bugged me.

  • Let me demonstrate how old school I am. The pseudo code in my op... it's Pascal

    tutorialspoint.com/pascal/pascal_repeat_until_loop.htm

    And yea, the Do While seems to be Java's equivalent.

    The While loop in Pascal seems pretty close to what you described in Rust. In Pascal, the moment the condition becomes true the loop breaks, and I didn't consider that it would work any differently in Construct.

    In my case, I needed to run through an array of 20,000 elements and check for a number of true conditions and make changes which could affect cells already examined in the loop, making them true. I needed to keep checking the array until all conditions were false.

    I don't need them often either which is why I haven't encountered this in Construct before, but when I do need one, there's just no good substitute.

    Thanks guys, I have been educated.

  • In every other language the While requires a condition.

    The conditions after the 'While' are the condition to repeat the while loop.

    So AFAICT you just want a 'While' condition followed by a "not found" condition, and that should do what you want.

  • I'm not that familiar with Pascal, although I believe Diego knows some. Depending on the language the source code is often compiled to a series of linear instructions. A "do...while" loop would compile to the conditional block followed by a conditional jump to the start. This is pretty similar to what pascal does ( probably not a coincidence ). A "while" loop has a conditional jump at the start that skips the entire block if the condition is false, and a normal jump at the end of the block that returns to the conditional section. I wasn't really sure what sort of notation to use here, so ended up with something like BASIC... ( had to outdo your pascal after all ;) ).

    do...while

    10 code
    20 conditional jump ( 10 )
    

    while

    10 conditional jump ( 40 )
    20 code
    30 jump ( 10 )
    40 ...
    

    Interestingly a C style "for" loop

    for (let i = 0 i < 10; i++) {
    	print(i);
    }
    

    is basically just sugar over the while loop

    10 let i = 10
    20 conditional jump ( 60 )
    30 code
    40 i = i + 1
    50 jump ( 20 )
    60 ...
    

    Can read more about it in the "Crafting interpreters" book, I think Writing A Compiler In Go talks about it as well but I can't remember.

  • ( had to outdo your pascal after all ;) ).

    I love you guys, I really do.

  • In my case, I needed to run through an array of 20,000 elements and check for a number of true conditions and make changes which could affect cells already examined in the loop, making them true. I needed to keep checking the array until all conditions were false.

    Based on your required algorithm, you don't need Loops (at least not directly), what you need is Recursion. Which means, you need one Function, which will have that algorithm to check all 20k items, find all/any found=true, make the changes you want, let it affect others, and then within that function call the same function (call itself) again. Technically, it should keep looping recursively, function within a function calling itself. Yeah, like the movie inception, except, you will keep calling the function only if found = true.

    Which means, let's say in the 500th recursion, if all the found = false, it won't repeat anymore.

  • Loops and recursion are interchangeable, so there's no particular requirement to have to use one or the other.

  • Which means, let's say in the 500th recursion, if all the found = false, it won't repeat anymore.

    While a good idea, in my case, a recursion would likely cause an even bigger delay in completion. Each cycle through the loop I'm looking at an element in the array. I'm then looking at the 9 elements surrounding it (x-1, y-1 to x+1, y+1) and basing changes off the results of that. Changing the element the loop is looking at could affect the element prior to it but I wouldn't know that until I ran through the loop again. (I'm playing with procedurally generating island terrain using an array as the template for the tileset.)

    And as an update, the While worked great, just like a good ole' Pascal repeat until. Here's the resulting code. It's purpose is to 'smooth' out the terrain generation. The OrphanCheck is the conditional to stop the while and the -1 in the array indicates it's a water tile. ArrayOffset is a 'border' around the islands that's guaranteed to be water.

    * On function 'EliminateOrphans'
    ----+ System: While
    -----> System: Set OrphanCheck to False
    --------+ System: For "IslandColumns" from ArrayOffset-1 to ArrayWidth-ArrayOffset
    ------------+ System: For "IslandRows" from ArrayOffset-1 to ArrayHeight-ArrayOffset
    ----------------+ System: Array.At(LoopIndex("IslandColumns"),LoopIndex("IslandRows")) ≠ -1
    -----------------> Array: Set ThisX to LoopIndex("IslandColumns")
    -----------------> Array: Set ThisY to LoopIndex("IslandRows")
    -----------------> Array: Set ArrayAve to 0
    -----------------> Functions: Call OrphanCount
    --------------------+ System: Array.ArrayAve ≤ 4
    ---------------------> Array: Set value at (LoopIndex("IslandColumns"), LoopIndex("IslandRows")) to -1
    ---------------------> System: Set OrphanCheck to True
    ---------------------> System: Add 1 to ArrayCount
    --------+ System: [X] Is OrphanCheck
    ---------> System: Stop loop
    
    * On function 'OrphanCount'
    ----+ System: For "IslandXCheck" from Array.ThisX-1 to Array.ThisX+1
    --------+ System: For "IslandYCheck" from Array.ThisY-1 to Array.ThisY+1
    ------------+ Array: Value at (LoopIndex("IslandXCheck"), LoopIndex("IslandYCheck")) ≠ -1
    -------------> Array: Add 1 to ArrayAve
    
    
    

    And to show what I'm doing and why I needed this, here's what the 'island' terrain looks like without running this loop.

    And after running the while loop

    Basically, it's purpose was doing some 'cellular automata' to check and see if a land tile had at least 3 neighboring tiles that were terrain and if not, set it back to a water tile (-1)

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)