Howdy, Stranger!

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

Looping woes

Passage tags has nobr
<<if $Si neq $L>>
<<$SuspectList[$Si]>>
<<set $Si +=1>>
<br>
Index =<<$Si>>
<<display 'Seating'>>
<<endif>>
<br>
<<if $Si eq $L>>
[img[BasicTrainInterGrid03.jpg]]
<<endif>>
What's suppose to happen;

Output list then when array length (defined in $L) is reached display image once.

Whats happening;
Correctly outputs the array list then displays the image the same amount of cycles of the loop below it after list output.

Both $Si is set to 0 and $L is defined after the array has been- in Start passage.

Why is this happening? The display passage should only apply to the first <<IF>> condition instructions.

Comments

  • I assume that the passage you've shown is "Seating", which is calling itself to loop.  And therein lies your problem, it's recursive.  Each time you call <<display 'Seating'>>, your calling that passage, which is modifying $Si.  Each passage "loop" does not return from the the call to <<display 'Seating'>> until the last one sets $Si to be equal to $L, at which point the recursive stack unwinds (in reverse).  Since, at that point, $Si is equal to $L, the conditional of your second <<if>> is always true.

    Try something like this: (merging your <<if>> macros)

    <<if $Si neq $L>>
    <<$SuspectList[$Si]>>
    <<set $Si +=1>>
    <br>
    Index =<<$Si>>
    <<display 'Seating'>>
    <br>
    <<else>>
    <br>
    [img[BasicTrainInterGrid03.jpg]]
    <<endif>>
  • Thanks MadExile for your reply. Yes 'seating' is the same passage. Your suggestion almost worked, I copied it over exact. Now the image displays twice. Once before the output of the array and once after.  Again Si and L are defined in Start and in my debug output both are showing the correct variables.

    Why is the image showing before the array output?  ??? I have managed a work around where the image displays on another passage, but I would like to know why this is happening for future reference and anyone else who may run into the same problem.
  • It shouldn't be.  You should only have the image appearing once, after the suspect list.

    I made an example to test with (see the attachment; it's the exact same recursive loop, but I changed the rest into debugging messages).  It produces this output (with both Twine 1.4.1 Sugarcane and SugarCube):

    [$Si: 0] ...SuspectList...
    [$Si: 1] ...SuspectList...
    [$Si: 2] ...SuspectList...
    [$Si: 3] ...SuspectList...
    [$Si: 4] ...SuspectList...
    ...Image...
    What are you using for the initial values for $Si and $L?  [EDIT] I assume $L is set to something like $SuspectList.length?
  • TheMadExile wrote:

    It shouldn't be.  You should only have the image appearing once, after the suspect list.

    I made an example to test with (see the attachment; it's the exact same recursive loop, but I changed the rest into debugging messages).  It produces this output (with both Twine 1.4.1 Sugarcane and SugarCube):

    [$Si: 0] ...SuspectList...
    [$Si: 1] ...SuspectList...
    [$Si: 2] ...SuspectList...
    [$Si: 3] ...SuspectList...
    [$Si: 4] ...SuspectList...
    ...Image...
    What are you using for the initial values for $Si and $L?  [EDIT] I assume $L is set to something like $SuspectList.length?


    Yes $L is for array length of the suspect list.  Thanks for your little demo. I discovered why I was getting two images, when I was having trouble originally I just worked around it by displaying the image in another passage which directed to the loop via <<display 'Seating'>> and guess what..my image display was there too. So when i went to try out your suggested reworking of the code I had forgot to remove the work around.  ::) But I was suffering from a bit of brain fade by that point and didn't realize my mistake until this morning. Duh. ::)

    But I thank you for your help because you did fix the original problem and it works now. I know how to do a loop properly now.  ;D

    *Update*
    Btw, is it possible to have that suspect list output as a passage link and have a variable attached like $SuspectX=$SuspectList[$Si] so the correct suspects name can be carried across when going to another passage? Two problems with this; Also $SuspectX is always going to be the last suspect on the list, so that isn't going to work.  And as soon as you add brackets for the index inside the passage link code it breaks it.
    I hope this makes sense?

  • I thought I replied to this. XD

    Was there anything in my How to Create Loops in Twine guide that needs expanded or better explained?
  • Dazakiwi38 wrote:

    Yes $L is for array length of the suspect list.


    That's what I figured.  In that case, unless you're using $L elsewhere, you could get rid of it entirely and redo the conditional of your <<if>> as:

    <<if $Si lt $SuspectList.length>>
    Just a suggestion.


    Dazakiwi38 wrote:

    *Update*
    Btw, is it possible to have that suspect list output as a passage link and have a variable attached like $SuspectX=$SuspectList[$Si] so the correct suspects name can be carried across when going to another passage? Two problems with this; Also $SuspectX is always going to be the last suspect on the list, so that isn't going to work.  And as soon as you add brackets for the index inside the passage link code it breaks it.
    I hope this makes sense?


    That is possible, yes.  While you can't do what you want directly in the vanilla headers, you can get fairly close (not entirely accurate, you can assign directly within certain restrictions, but what I'm going to suggest will be less problematic).  Instead of assigning the value of $SuspectList[$Si] to $SuspectX, simply assign the index, $Si, and then use that in the follow-on passage.

    For example: (updated example in the attachment)

    <<if $Si lt $SuspectList.length>>
    <<print "[[" + $SuspectList[$Si] + "|Chosen Suspect][$SuspectX = " + $Si + "]]">><br>
    <<set $Si++>>
    <<display "Seating">>
    <<else>>
    [img[BasicTrainInterGrid03.jpg]]
    <<endif>>
    Then in the follow-on passage, you can just reference the selected suspect via $SuspectList[$SuspectX].  The attached example shows what I mean in a little more detail.
Sign In or Register to comment.