0 votes
by (230 points)

I'm not sure on the exact terminology of this, but is it possible to create a series of variables (i.e. in a loop)?

e.g. something like:
 

(set: $a to 0)
(for: each _x, ...$array)[
(set: $a to it+1)
(set: $variable + $a to $a)
]

The idea being that variables named $variable1, $variable2, etc. will be created (with the values, 1, 2, etc. in this case).

Originally I wanted to use it to generate an appropriate amount of numbered links to match the amount of items in an array (the rising number in the for loop worked for making the links themselves, but the data in them also relied on that rising number and they don't get executed until later, so it wouldn't work without a variable that keeps its value long enough) but now I'm just wondering if creating multiple variables is possible at all. I feel like I've read something on it before but hours of searching got me nowhere.

1 Answer

0 votes
by (23.6k points)
selected by
 
Best answer

I think for what you are planning to do, it would be better and easier to just store your data in an array:


(set: $myArray to (a:))
(set: $a to 0)
(for: each _x, ...$array)[
(set: $myArray to it + (a:("variable" + $a.toString())))
(set: $a to it+1)
]

Now you can call the name and the corresponding number in this way:

(print: $myArray's 1)

(print: $myArray.indexOf(("variable0")))

 

by (230 points)

I wish the Harlowe documentation pages had all these ".length" ".toString" ".indexOf" type modifiers on them so I know they exist. It took me ages to figure out that "$example's 1" etc worked fine instead of having to use 1st the way the documentation says.

I'm not sure if that would help... I'll post the full code:

Passage "p1" :

{
(set: $ArrayAnswer to (words: "h e y"))
(set: $ArrayCurrent to (a:))

<!-- sets ArrayCurrent to ???s of appropriate length -->
(for: each _letter, ...$ArrayAnswer)[
  (set: $ArrayCurrent to it + (a: "?"))
]
}
|displayer>[(display: "p2")]

<!-- displayed by p2 once complete -->
|end)[Congratulations!]

{
<!-- Working Version -->
(link: "1")[
  (set: $ArrayCurrent's 1 to $ArrayAnswer's 1)
  (replace: ?displayer)[(display: "p2")]
]
(link: "2")[
  (set: $ArrayCurrent's 2 to $ArrayAnswer's 2)
  (replace: ?displayer)[(display: "p2")]
]
(link: "3")[
  (set: $ArrayCurrent's 3 to $ArrayAnswer's 3)
  (replace: ?displayer)[(display: "p2")]
]
}

{
<!-- Not Working -->

(set: $x to 0)
(for: each _a, ...$ArrayAnswer)[
  (set: $x to it+1)
  (link: "$x")[
    (set: $ArrayCurrent's $x to $ArrayAnswer's $x)
    (replace: ?displayer)[(display: "p2")]
  ]
]
}

Passage "p2" :

{
(if: $ArrayCurrent is $ArrayAnswer)[
  (show: ?end)
]

<!-- display current progress -->
(text: ...$ArrayCurrent)
}

 

The idea is to be able to set a word for the first array, and have the rest of the page generate based on how long that array is. If I manually set the links with the correct numbers, as shown above, then it works fine.

Below it I tried to make a for loop to generate the links, which works, but by the time the links are actually clicked, they're all set to the max number rather than their appropriate numbers. Even if I create an array full of integers, by the time the link code is processed, I can't think of any way to have the right values placed in each one.

by (23.6k points)

Look at @greyelf's answer here. I think it touches on the exact problem you have.

by (230 points)
Ahh, so basically you can use (print:) and make text clones of the value at the time.

I missed that post when I was searching - thanks!
by (159k points)

I wish the Harlowe documentation pages had all these ".length" ".toString" ".indexOf" type modifiers on them so I know they exist

The main reason it doesn't is that they are not Harlowe modifiers or part of the Harlowe TwineScript language. Each of the properties / functions you listed actually belong to the Javascript language, which is the programming language your web-browser uses to interact with the web-page being generated / displayed, and is the language that the Harlowe engine is written in.

ex. the Javascript documentation for:
<String>.length
<Array>.length
<Object>.toString()
<String>.indexOf()
<Array>.indexOf()

by (230 points)
Oh, that's interesting. I didn't know that, thank you!
...