How to efficiently encode 'if value 1 = A, then set value 2 to B' with 100 different values each for A and B paired up?

Hello!

I'm a newbie when it comes to Quest, but I was wondering about how to go about the following, in the most efficient way.

I would like to set a variable, called "Threshold", to a specific whole number (integer) value, based on what (integer) value another variable, called "ARV", is currently set to. In a spreadsheet, I've made pairings of corresponding "ARV" and "Threshold" values. There are about 100 pairings based on 100 possible values that ARV can take (from 1 up to 100).

The idea is that the game should check 'what is the current value for ARV?' and then set the value for Threshold accordingly.

So this could perhaps be done with a script, but I don't know if 100 lines of this won't cause the system to bug out:
If variable ARV = 1, then set variable Threshold to 101.
Elseif variable ARV = 2, then set variable Threshold to 104.
Elseif variable ARV = 3, then set variable Threshold to 105.
...

I'm wondering if there is a sort of quick list (system) you can easily use in Quest where two values are stored as pairs. Then if value A (from variable ARV) equals value 1 (for ARV) stored in the list, the value in that list paired with value 1 (the value for Threshold) is automatically returned from said list in some way. Maybe this would eliminate the need for 100 lines of conditions in a script?

Please keep in mind I'm a complete newbie so in-depth answers would be much appreciated. By that I mean, please explain your reasoning for a solution, as well as describing step by step how to implement the solution exactly.

Thanks for any help!


Is there a predictable relationship between the two values? If there is, you could include some kind of formula.

If not, I'd suggest making a list of possible values. In code view, I think it would look something like:

<thresholdvalues type="list">
  <value type="int">0</value>
  <value type="int">101</value>
  <value type="int">104</value>
  <value type="int">105</value>
…
</thresholdvalues>

Probably placed inside the game element, unless an object is more relevant.

You can then use faster code, such as:

Threshold = ListItem (game.thresholdvalues, ARV)

(Note: I added a dummy value at the beginning of the list, because lists are numbered from 0)

Or, if it would take too long to put all those values from your spreadsheet into the list, you could do:

firsttime {
  game.threshold_values = Split("0;101;104;105;106;etc …")
}
Threshold = ToInt (ListItem (game.threshold_values, ARV))

Most spreadsheets will let you copy a row of items as a list with tab characters or commas in between; so if you want to avoid copying out the whole list manually, you could try pasting them into a text editor and use search and replace to put semicolons between instead. Again, I put a 0 in between for the case where ARV is 0, which I think you said won't happen.


Hi! Thank you very much for the reply.

To answer some of the questions/considerations you brought up:

  • Is there a predictable relationship between the two values?

No relationship that could be expressed in one easy formula, and/or using simple steps. It's definitely much easier to just write the answers down to be read when the game needs them, so to speak.

  • Probably placed inside the game element, unless an object is more relevant.

I don't think a designated object is relevant, it would pretty much just be a list that I'd want to access anytime using any relevant script. So I think the game object is probably the way to go for me then. :)

  • Or, if it would take too long to put all those values from your spreadsheet into the list, you could do...

I don't particularly mind taking the time to manually copy them. I am curious though, is there a functional difference or any kind of caveat that goes with using the second method as opposed to the first?

  • I added a dummy value at the beginning of the list, because lists are numbered from 0. [...] I put a 0 in between for the case where ARV is 0, which I think you said won't happen.

You're correct, the range of values that ARV can take would go from 1 up to 100, excluding 0. I presume you include the dummy then, so that the 'ARV' in the code can be read directly from the ARV variable, and the list will automatically produce the corresponding value it has stored for that position. Position 1 - 100 being filled with the values, whereas position 0 (filled with value 0) should technically never be called upon because the ARV variable should never be set to 0.

Now, if you were to insist to put the values in from the very first position in the list (so without wasting a position on a dummy value), could you then write something like...

Threshold = ListItem (game.thresholdvalues, ARV - 1)

and would Quest still be able to automatically read in the value from the ARV variable, subtract 1, and then use that value as an indicator for the position in the list? Or would you need to create a second variable "ARVadjusted", set ARVadjusted to ARV - 1, and adjust the code to read ARVadjusted rather than ARV. (Threshold = ListItem (game.thresholdvalues, ARVadjusted))

In any case, I'm very grateful for your help!


I am curious though, is there a functional difference or any kind of caveat that goes with using the second method as opposed to the first?

Either way works well. The main difference is that using Split gives an array of strings, so if you want to compare the resulting threshold to another number, you'll need to use ToInt on it first.

The real reason I quoted two methods was because I wasn't 100% sure on the XML syntax for a list.

Now, if you were to insist to put the values in from the very first position in the list (so without wasting a position on a dummy value), could you then write something like...
Threshold = ListItem (game.thresholdvalues, ARV - 1)

Yes, that works fine. I'd normally suggest that; but experience on here shows that a lot of people will end up using the list elsewhere, and miss out the -1 in just one place, leading to errors that are very hard to track down. Seems that adding a dummy zeroth element is sometimes easier to understand for people without a programming background.

Use whichever method feels most natural to you :) But I'd advise against mixing them, because that makes it easier to slip up.


I see. I think I'll use the first method so the values are stored as integers from the get-go, since I will be using a lot of comparisons of other numbers to the Threshold value. And I probably will put in a dummy first element just so that I can refer to the ARV value directly, and pull the corresponding value for that element of the list. It's something I could definitely see myself losing track of later down the line, otherwise.

Alrighty, thank you very much!


I'm probably not understanding what you want, and mrangel already has helped you, but if you just want pairings (input -> output), quest has 'dictionary' Attributes for that:

https://docs.textadventures.co.uk/quest/using_dictionaries.html

a quick simple example:

(would of course need a bit more coding and adjusted coding for using your own VARIABLES with it, for its actual working application/usage for your game)

<game name="NAME_OF_GAME">

  <attr name="start" type="script">
    msg (StringDictionaryItem (example_object.example_dictionary_attribute, "1"))
    msg (StringDictionaryItem (example_object.example_dictionary_attribute, "one"))
    msg (StringDictionaryItem (example_object.example_dictionary_attribute, "2"))
    msg (StringDictionaryItem (example_object.example_dictionary_attribute, "two"))
    msg (StringDictionaryItem (example_object.example_dictionary_attribute, "3"))
    msg (StringDictionaryItem (example_object.example_dictionary_attribute, "three"))
  </attr>

</game>

<object name="example_object">

  <example_dictionary_attribute type="stringdictionary">

    <item>
      <key>1</key>
      <value>one</value>
    </item>

    <item>
      <key>one</key>
      <value>1</value>
    </item>

    <item>
      <key>2</key>
      <value>two</value>
    </item>

    <item>
      <key>two</key>
      <value>2</value>
    </item>

    <item>
      <key>3</key>
      <value>three</value>
    </item>

    <item>
      <key>three</key>
      <value>3</value>
    </item>

  </example_dictionary_attribute>

</object>

-------------------

// output:

one
1
two
2
three
3

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums