Learning (or trying to learn) how to use: For...

  • for is a general loop method which will need more details about the length of your list so that it will not exceed the bounds (go past the end) of the list.
 for (myItem, 0, ListCount(myList) - 1) {
   msg ("Current item is " + ObjectListItem(myList,myItem).name)
 }

Can anyone break this down?

I'm gonna give it a shot.

Here's what I come up with:

  • for (myItem,

    To choose an integer (a variable, which will be called 'myItem') ...

  • 0,
    ...starting from the first item...

  • ListCount(myList) - 1)
    (finds (how many items are on myList) then subtracts 1)
    ((I believe this is to find the actual index number of the last item on myList. It finds how many items are on the list, but the first item is indexed as '0', so the index number of the last item on the list is number of items on the list minus 1.))

  • ObjectListItem(myList,myItem)
    So, if myList had 3 items on it, indexed 0, 1, and 2, this would return the object name of each one, one at a time.

  • ObjectListItem(myList,myItem).name)
    ...this actually displays the name of each object, though. (Rather than "Object: object_name_here")


for


for (iterator variable, int from, int to) { script }

As of Quest 5.1 there is an optional “step” parameter:


for (iterator variable, int from, int to, int step) { script }

Run a script multiple times, incrementing the iterator variable between the specified limits. If a “step” parameter is specified, the iterator variable will be incremented by that amount each time (if not specified, the default step size is 1).


  • int step
    This is the value the variable, myItem, will be increased by after each loop.
    So, if I had 10 items on myList, and only wanted to print every other item on myList, int step would need to be 2?

That is correct.

But a better way is to use foreachin this case (and most cases; I use foreach far more than for). It iterates with an object over a list, rather than an int, from a start to end.

 foreach (myItem, myList) {
   msg ("Current item is " +myItem.name)
 }

Note that you cannot change the list whilst iterating over it in this way.

http://docs.textadventures.co.uk/quest/guides/using_lists.html


Hi, Pixie!

HegemonKhan was describing how loops work here: http://textadventures.co.uk/forum/quest/topic/rilbsoulbeo5xapbvpotzw/still-suffering-with-result

To keep from taking over AND straying from the original topic of the post, I thought it best to start a new thread.

I've always found anything with more than 2 parameters daunting, so I thought for would be a good one to tackle first.

I usually realize what I'm doing wrong (or at least part of what I'm doing wrong) while writing these posts. (This is probably because I'm going over my problem in my mind, one step at a time, in an attempt to clearly illustrate exactly what it is I'm trying to accomplish. Anyway...)


Note that you cannot change the list whilst iterating over it in this way.

Word?!? I can change the list using for? (Slaps forehead.)

I could use that to keep a list from getting longer than, say... 3 strings. (I.e., you can only know three spells at once.)

for (myItem, 0, ListCount(myList) - 1) {
   msg ("Current item is " + ObjectListItem(myList,myItem).name)
 }

No...

Probably better off with this:


if (ListCount(mySpellsList) > 3)) {
  list remove (mySpellsList, 0)
}

Wait... can I do it by the item number?

Or should I change that to:


if (ListCount(mySpellsList) > 3)) {
  list remove (ObjectListItem(mySpellsList, 0))
}

Theory: I could set the int step to 2 to print a different msg for every other object on a list.


for (myItem, 0, ListCount(myList) - 1, 2) {
   msg ("Current item is an odd number. It's display name is " + ObjectListItem(myList,myItem).name)
 }

http://docs.textadventures.co.uk/quest/guides/using_lists.html

I hope to learn how to use everything on this page over the next day or two, one block of code at a time.


foreach is definitely my GOTO loop script command. (Oh, the ambiguity of that statement!)


(Sorry, I'm scatter-brained at the moment, and my writing is reflecting it.)


(filler to get past the post edit restricts)
(filler to get past the post edit restricts)


@ Richard:

(HK edit: nevermind, your code worked, I wasn't paying close enough attention to it, my bad)

to get the List's/Dictionary' Values:

(you have to then do something with that VALUE: use it in/for a Function call's Argument or store it into a VARIABLE, as you can't just have a VALUE "hanging" in code, not doing anything)

VALUE (String Value) = StringListItem (LIST, INDEX_NUMBER)
VALUE (Object reference/pointer Value) = ObjectListItem (LIST, INDEX_NUMBER)

VALUE (String Value) = StringDictionaryItem (DICTIONARY, STRING_KEY)
VALUE (Object reference/pointer Value) = ObjectDictionaryItem (DICTIONARY, STRING_KEY)
VALUE (Script Value) = ScriptDictionaryItem (DICTIONARY, STRING_KEY)

here's an example (a complex one, to show you how it works):

<attr name="my_list" type="simplestringlist">hi;hola;bye;adios</attr>
<attr name="my_dict" type="simplestringdictionary">hi = hola; hola = hi; bye = adios; adios = bye</attr>

// scripting:

list_count_integer_variable = ListCount (my_list)
last_index_integer_variable = list_count_integer_variable - 1
random_integer_variable = GetRandomInt (0, last_index_integer_variable)
list_item_string_variable = StringListItem (my_list, random_integer_variable)
dict_item_string_variable = StringDictionaryItem (my_dict, list_item_string_variable)
msg (dict_item_string_variable)

// --------

or as a single line of code (if you prefer):

dict_item_string_variable = StringDictionaryItem (my_dict, StringListItem (my_list, GetRandomInt (0, ListCount (my_list) - 1)))

// ------------------------------

// result/output:

(randomly, one of these:

hi
hola
bye
adios


I'm not sure if for the 'list remove' if you can use an index number, or if you have to use the item itself (the String):

my_list = split ("red;blue;yellow", ";")

can you also do this:
list remove (my_list, 0) // removes the "red" item
or, do you have to do it like this:
list remove (my_list, "red") // removes the "red" item



list_count_integer_variable = ListCount (my_list)
last_index_integer_variable = list_count_integer_variable - 1
random_integer_variable = GetRandomInt (0, last_index_integer_variable)
list_item_string_variable = StringListItem (my_list, random_integer_variable)
dict_item_string_variable = StringDictionaryItem (my_dict, list_item_string_variable)
msg (dict_item_string_variable)

Aha!

I was going to ask how to pull a random object from the player's inventory before I finished porting my game.

(You must have that foresight stuff...)


I was going to ask how to pull a random object from the player's inventory before I finished porting my game.

This will remove a random object from the inventory, and dump it on the ground.:

obj = PickOneObject(ScopeInventory())
obj.parent = player.parent

[Expletive deleted] awesome!


<turnscript name="dropsies">
      <enabled />
      <script>
        if (RandomChance(10)) {
          obj = PickOneObject(ScopeInventory())
          msg ("Blah, blah, blah... and you drop "+GetDisplayName(obj)+".")
          obj.parent = player.parent
        }
      </script>
    </turnscript>

PickOneObject is not in 5.6, so I created a function called PickOneObject:


<function name="PickOneObject" parameters="lst" type="object">
    n = ListCount(lst)
    if (n = 0) {
      return (null)
    }
    index = GetRandomInt(0, n - 1)
    return (ObjectListItem(lst, index))
  </function>

Quest 5.7 is kind of out. It is now on the web player. For desktop you can get it here:
https://github.com/textadventures/quest/releases


Quest 5.7 is kind of out. It is now on the web player. For desktop you can get it here:
https://github.com/textadventures/quest/releases

Nice!


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

Support

Forums