Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Loop for a limited number of times

I am a complete coding beginner and have spent some time searching the archives but I can't seem to find an answer. I'm using Harlowe and trying to write a passage that loops for a fixed number of times before changing. So, 'add sugar' for up to four times and then go to the passage "sweet enough already" on the fourth click.

I've got the loop to work ok but I have no idea how to count the number of loops and change the result based on said count. I'd be grateful for any pointers, and am keen to understand how things work rather than just copying and pasting!

Many thanks

Comments

  • Since you asked for how things work, here's a short primer on loops.

    In JavaScript, a simple loop will often look like this:
    for ( var i = 0;
          i < 4;
          i++) {
    // stuff
    }
    
    Which, in plain English, means:
    for ( a variable called "i" with initial value of 0;
          if "i" is less than 4;
          do the code below, then add 1 to "i" and run this 'for loop' again) {
    // the code we want to run
    }
    
    So all we need to do is take that logic of the loop above and translate into passages.

    First, we have our passage where we initialize the variable with how many lumps of sugar we have (none) and provide a link to a passage where the 'loop part of the loop' is going to take place:
    ## Setup
      I need to put sugar in my coffee.
      (set: $amountOfSugar to 0)
    
      [[Add Sugar]]
    
    Then, we have a second passage which we're going to visit a couple times. Each time it increments the amount of sugar we have, then displays two options for text. If we have less than four lumps of sugar, we give the player a link to re-visit this passage—which is the same as repeating our loop. I also included a link for any weirdos who don't want extra-sweet coffee.

    If we have four lumps (or more), we no longer have the option to re-visit the passage—which is analogous to saying "don't loop any more".
    ## Add Sugar
      (set: $amountOfSugar to $amountOfSugar+1)
    
      (if: $amountOfSugar < 4)[
        My coffee has (print: $amountOfSugar) lumps of sugar in it.
    
        [[That's Enough]]
        [[Add More Sugar->Add Sugar]]
        ](else:)[
        My coffee has at least four lumps of sugar in it.
    
        [[That's More Than Enough->That's Enough]]
      ]
    
    (by the way, if you wanted the incrementing to happen upon clicking the link rather than visiting the passage, there's a pattern for making setter links in Harlowe)

    I hope this helps and is what you're looking for. It's often helpful to see the code being asked about when answering a code question, so if this isn't quite the right answer, please post the text you tried.
  • edited July 2016
    You don't actually need to loop the passage to do what you want, you could use a combination of a (link-repeat: ) macro, a named hook, and a (go-to: ) macro to implement a solution within a single passage. This has the advantage of not adding un-needed passage names to your History.
    You taste your drink and []<sweetness|it is not sweet enough.
    
    {
    (set: $cubes to 0)
    (link-repeat: "add sugar")[
    	(set: $cubes to it + 1)
    	(if: $cubes < 4)[
    		(replace: ?sweetness)[(print: "even with $cubes cube(s) of sugar ")]
    	](else:)[
    		(go-to: "sweet enough already")
    	]
    ]
    }
    
    note: I added indentation and extra line-breaks to the above to make it more readable, they can be safely removed.
  • Thank you so much for your help, derektb and greyelf. derektb, your solution was just what I was I looking for, and it was great to have the JavaScript underpinnings to make sense of what was going on. greyelf, I think my coding is not quite up to your solution yet - but thanks for taking the time to reply!
Sign In or Register to comment.