Still suffering with result =

Heya,

It got explained to me before, how to make it so various inputs do the same thing but I'm still having trouble implementing it. I thought I'd attach an image just to make it clear where I seem to be having trouble. I'm trying to make it so that typing W, West, west and w would all have the same function for a get input script. But I can't seem to pin down the variation to get this to work, if it can be done.

http://i.imgur.com/L6Aclmt.png

Would be a great help if anyone can tell me where I'm going wrong.


you merely have the wrong syntax, here's the fix (and a bit of refinement for it too):

if [EXPRESSION] LCase (result) = "e" or LCase (result) = "east"
  // then -> add new script -> 'WHATEVER' Script
else if [EXPRESSION] LCase (result) = "w" or LCase (result) = "west"
  // then -> add new script -> 'WHATEVER' Script
else if [EXPRESSION] LCase (result) = "n" or LCase (result) = "north"
  // then -> add new script -> 'WHATEVER' Script
else if [EXPRESSION] LCase (result) = "s" or LCase (result) = "south"
  // then -> add new script -> 'WHATEVER' Script
else
  // then, -> add new script -> 'output' section/category -> 'print a message' Script -> print [MESSAGE] Wrong input, try again.

about my code above:

the 'LCase (STRING_VALUE)' Function takes, whatever the combination of upper and lower case letters, of the inputted string value, and turns it all into lower case letters. So, if I inputted 'E', it's converted into 'e', and if I inputted 'EAST/East/eAst/etc many combinations lol', it's converted into 'east'. Now, that converted "e" is compared to "e", which is a match (TRUE), and it does the nested script(s) for it. Or, now that converted "east" is compared to "east", which is a match (TRUE), and it does the nested script(s) for it.

If I inputed 'W' or 'WEST/etc many combinations', it's converted into "w" or "west", which does NOT match up with "e" nor "east", so we go to the first 'else if', which does compare it to "w" or "west", which is a match (TRUE), and thus does its nested script(s)

If I inputed 'N' or 'NORTH/etc many combinations', it's converted into "n" or "north", which does NOT match up with "e" nor "east", so we go to the first 'else if', which does NOT match up with "w" nor "west", so we go to the second 'else if', compare it to "n" or "north", which is a match (TRUE), and thus does its nested script(s)

If I inputed 'S' or 'SOUTH/etc many combinations', it's converted into "s" or "south", which does NOT match up with "e" nor "east", so we go to the first 'else if', which does NOT match up with "w" nor "west", so we go to the second 'else if', which does NOT match up with "n" nor "north", so we go to the third/last 'else if', compare it to "s" or "south", which is a match (TRUE), and thus does its nested script(s)

If I inputed 'b' or 'BLAH/etc many combinations', it's converted into "b" or "blah", which does NOT match up with "e" nor "east", so we go to the first 'else if', which does NOT match up with "w" nor "west", so we go to the second 'else if', which does NOT match up with "n" nor "north", so we go to the third/last 'else if', which does NOT match up with "s" nor "south", so we go to the 'else', (as it has no condition being checked/compared for matching), DOING its nested script(s)


if
LCase (result) = "e"
or
LCase (result) = "east"
else if
LCase (result) = "w"
or
LCase (result) = "west"
else if
LCase (result) = "n"
or
LCase (result) = "north"
else if
LCase (result) = "s"
or
LCase (result) = "south"
else

the 'if', the 3 'else ifs', and 'else' are the command/action being done

and, since it's the 'if' (if/else-if/else) Script (for this example), we're checking its conditions, which are (in this example):

LCase (result) = "e"
LCase (result) = "east"
LCase (result) = "w"
LCase (result) = "west"
LCase (result) = "n"
LCase (result) = "north"
LCase (result) = "s"
LCase (result) = "south"

for whether they are 'TRUE' or 'FALSE'

(if none of the conditions are TRUE, then we do the else's nested script/s)

lastly, the 'or' is a logic/boolean operator/operation


Basic Boolean Logic / Truth Tables:

(Venn Diagrams are a great way to understand this Boolean logic)

https://en.wikipedia.org/wiki/Truth_table
https://lib.colostate.edu/howto/others/venn.html (Venn Diagram examples)
https://en.wikipedia.org/wiki/Boolean_algebra (it can be written as math equations, but with a few differences, also see: Symbolic Boolean Logic/Arithmetic: see link below)
http://philosophy.lander.edu/logic/symbolic.html (symbolic logic/arithmetic) (click on the 'next' buttons at the bottom, there's more pages on this stuff)
https://en.wikipedia.org/wiki/Logic_gate (computer architecture = digital design = circuitry)
https://learn.sparkfun.com/tutorials/digital-logic (computer architecture = digital design = circuitry)
etc etc etc resources

Identity logic:

true ---> TRUE
false ---> FALSE

Negation (not) (opposite / compliment) logic:

not true ----> FALSE
not false ----> TRUE

'AND' logic:

true and true ---> TRUE
true and false ---> FALSE
false and true ----> FALSE
false and false ----> FALSE

'OR' logic:

true or true ---> TRUE
true or false ---> TRUE
false or true ---> TRUE
false or false ---> FALSE


how it checks for 'TRUE' or 'FALSE' :

string matching comparison checking:

VARIABLE = "HegemonKhan"
// if [VARIABLE] = ("HegemonKhan")
// does ["H"] = ("H") ----> true
// does ["e"] = ("e") ----> true
// does ["g"] = ("g") ----> true
// does ["e"] = ("e") ----> true
// does ["m"] = ("m") ----> true
// does ["o"] = ("o") ----> true
// does ["n"] = ("n") ----> true
// does ["K"] = ("K") ----> true
// does ["h"] = ("h") ----> true
// does ["a"] = ("a") ----> true
// does ["n"] = ("n") ----> true
// indeed, ["HegemonKhan"] = ("HegemonKhan") -----> TRUE

VS

VARIABLE = "HegemonKhan"
// if [VARIABLE] = ("Hegemonkhan")
// does ["H"] = ("H") ----> true
// does ["e"] = ("e") ----> true
// does ["g"] = ("g") ----> true
// does ["e"] = ("e") ----> true
// does ["m"] = ("m") ----> true
// does ["o"] = ("o") ----> true
// does ["n"] = ("n") ----> true
// does ["K"] = ("k") ----> false
// nope, ["HegemonKhan"] = ("Hegemonkhan") -----> FALSE

VS

VARIABLE = "Hegemonkhan"
// if [VARIABLE] = ("HegemonKhan")
// does ["H"] = ("H") ----> true
// does ["e"] = ("e") ----> true
// does ["g"] = ("g") ----> true
// does ["e"] = ("e") ----> true
// does ["m"] = ("m") ----> true
// does ["o"] = ("o") ----> true
// does ["n"] = ("n") ----> true
// does ["k"] = ("K") ----> false
// nope, ["Hegemonkhan"] = ("HegemonKhan") -----> FALSE

VS

VARIABLE = "HegemonKhan"
// if [VARIABLE] = ("A")
// does ["H"] = ("A") ----> false
// nope, ["HegemonKhan"] = ("A") -----> FALSE

VS

VARIABLE = "A"
// if [VARIABLE] = ("HegemonKhan")
// does ["A"] = ("H") ----> false
// nope, ["A"] = ("HegemonKhan") -----> FALSE


Unfortunately, your syntax only works for string lists, not separate possible string results.


for what you (JK) tried to do in your code ( http://i.imgur.com/L6Aclmt.png ), it would look like this (in correct usage and syntax):

east_stringlist_variable = split ("e;east", ";")
west_stringlist_variable = split ("w;west", ";")
north_stringlist_variable = split ("n;north", ";")
south_stringlist_variable = split ("s;south", ";")

handled_boolean_variable = false

get input {
  foreach (string_variable, east_stringlist_variable) {
    if (LCase (result) = string_variable) {
      // do whatever you want to do
      handled_boolean_variable = true
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, west_stringlist_variable) {
      if (LCase (result) = string_variable) {
        // do whatever you want to do
        handled_boolean_variable = true
      }
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, north_stringlist_variable) {
      if (LCase (result) = string_variable) {
        // do whatever you want to do
        handled_boolean_variable = true
      }
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, south_stringlist_variable) {
      if (LCase (result) = string_variable) {
        // do whatever you want to do
        handled_boolean_variable = true
      }
    }
  }
  if (not handled_boolean_variable) {
    msg ("Wrong input, try again")
  }
}

or if you don't like my usage of the 'LCase' stuff, it'd look like this:

(but by not using the 'LCase', an input of, for example, 'EAST', would result in the scripting displayed/output of: Wrong input, try again)

(unless, you were to put in every combination into your 'split' Functions...)

(e/w = 2^1 = 2 = e, E = 2)
(east/west = 2^4 = 16 = east, easT, eaSt, eaST, eAst, eAsT, eASt, eAST, East, EasT, EaSt, EaST, EAst, EAsT, EASt, EAST = 16)
[ east_stringlist_variable = split ("e; E; east; easT; eaSt; eaST; eAst; eAsT; eASt; eAST; East; EasT; EaSt; EaST; EAst; EAsT; EASt; EAST", ";") ]

(north/south = 2^5 = 32 = HELL NO! lol)

east_stringlist_variable = split ("E;e;East;east", ";")
west_stringlist_variable = split ("W;w;West;west", ";")
north_stringlist_variable = split ("N;n;North;north", ";")
south_stringlist_variable = split ("S;s;South;south", ";")

handled_boolean_variable = false

get input {
  foreach (string_variable, east_stringlist_variable) {
    if (result = string_variable) {
      // do whatever you want to do
      handled_boolean_variable = true
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, west_stringlist_variable) {
      if (result = string_variable) {
        // do whatever you want to do
        handled_boolean_variable = true
      }
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, north_stringlist_variable) {
      if (result = string_variable) {
        // do whatever you want to do
        handled_boolean_variable = true
      }
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, south_stringlist_variable) {
      if (result = string_variable) {
        // do whatever you want to do
        handled_boolean_variable = true
      }
    }
  }
  if (not handled_boolean_variable) {
    msg ("Wrong input, try again")
  }
}

Heya HK, really helpful as always! ^__^

Although I still might not be doing it right following the example.

Error running script: Error compiling expression 'LCASE (result) = "e" or LCASE (result) "east"': AndOrElement: Operation 'Or' is not defined for types 'Boolean' and 'String'

msg ("The sky above is dominated by dark cloud... its not going to be friendly.</b>")
get input {
if (LCASE (result) = "e" or LCASE (result) "east") {
  msg ("Against your better judgement, you decide to head east...")

I'm assuming this means that I can't use the or function in an expression? Or is there some specific way to phase this. What you wrote looks quite complicated.

Ah, but now I read more into your second post...

east_stringlist_variable = split ("e;east", ";")
west_stringlist_variable = split ("w;west", ";")

get input {
  foreach (string_variable, east_stringlist_variable) {
    if (LCase (result) = string_variable) {
      msg ("Against your better judgement, you decide to head east...")
      handled_boolean_variable = true
    }
  }
  if (not handled_boolean_variable) {
    foreach (string_variable, west_stringlist_variable) {
      if (LCase (result) = string_variable) {
        msg ("Alternatively you go west.")
        handled_boolean_variable = true
      }
    }
  }

  if (not handled_boolean_variable) {
    msg ("Wrong input, try again")
  }
}

I'll go give this a go. Just putting down my thoughts in case anyone stumbles onto the same problems.


Hello!

This seems to work, but it doesn't move the player.

(I've been thinking of incorporating a gimmick such as this recently, myself.)

Is there a way to print the message and still go somewhere?

Would it need to be in an 'After exiting' room script?

Or do I just need to cool my jets and read the entire post before asking all these questions?


More on this as it comes in. . .


Heya Richard,

I'm working with a function here rather than actually going anywhere. It changes some dialogue as part of an intro scene, consider it more like picking your starting area.

You'd just incorporate a move object thing.

 }
  if (not handled_boolean_variable) {
    foreach (string_variable, west_stringlist_variable) {
      if (LCase (result) = string_variable) {
        msg ("Alternatively you go west.")
        handled_boolean_variable = true
        MoveObject (player, Corrupted Town)
}

Oh, I gotcha!

get input {
  foreach (string_variable, east_stringlist_variable) {
    if (LCase (result) = string_variable) {
      msg ("Against your better judgement, you decide to head east...")
      handled_boolean_variable = true
      HandleSingleCommand ("e")
    }
  }
  if (not handled_boolean_variable) {   
    foreach (string_variable, west_stringlist_variable) {
      if (LCase (result) = string_variable) {
        msg ("Alternatively you go west.")
        handled_boolean_variable = true
        HandleSingleCommand ("w")
      }
    }
  }
  if (not handled_boolean_variable) { 
    msg ("Wrong input, try again")
  }
}

It doesn't print the message when I go west for the first time, but it does every time I go west after the first time.

If I move the foreach for the west_stringlist_variable above the one for the east_string_variable, west prints the message from the jump, but east doesn't print the message the first time.


Did you get your code working? Or is this the same issue you're running into? (The case being upper or lower has no bearing on my end. E, e, East, east, and EAST all go east.)


@ JK:

you just are not writing/typing in the correct spelling of the Functions, yes they have to be exact (quest is case sensitive):

you typed wrongly: LCASE (result)

there is no 'LCASE' Function in quest, hence the (unfortunately mis-leading/poor worded) error message

but, there is a 'LCase' Function, so to correct it, using this example of yours (fixed up):

you also were missing the 2nd condition's equal sign too (I just noticed this mistake myself, I almost missed it in your code, lol):

... or LCASE (result) "east"

corrected:

... or LCase (result) = "east"

msg ("The sky above is dominated by dark cloud... its not going to be friendly.</b>")
get input {
if (LCase (result) = "e" or LCase (result) = "east") {
  msg ("Against your better judgement, you decide to head east...")

a little more about this, as I didn't explain how the comparisons work for many conditions and the boolean logic operators (and/or/not):

if (LCase (result) = "e" or LCase (result) = "east") {

quest either starts from the left or the right (barring any order of operation rules: same as the ones for math, for example something in a parenthesis is done first before something outside of a parenthesis, using math as example: 5 * (4 + 3) = 35, not 23)

so first it compares:

LCase (result) = "e" (or) LCase (result) = "east"

which will result in: 'true' (or) 'false'

it then compares the other one:

LCase (result) = "east" (or) LCase (result) = "e"

which will result in: 'true' (or) 'false'

it then does a last comparison of the two Values of 'true/false'

which will result in an ultimate/final: 'TRUE' (or) 'FALSE', which will determine whether it does the nested script(s) or jumps to the first 'else if' or the next 'else if' or the optional 'else'.

an example will probably make more sense:

(let's just start from the left side, as that is how we read, at least in the western world anyways)


result = "e"

if (LCase (result) = "e" or LCase (result) = "east") {

first we do this:

is "e" = "e" ----> true

it's done, due to the rest of if's expression (it doesn't even need to try the second condition: or ... = "east") -----> TRUE, it does the nested script(s)

'OR' logic:

true or true = TRUE
true or false = TRUE
false or true = TRUE
false or false = FALSE

notice:

true or true = TRUE
true or false = TRUE

it doesn't matter whether the 2nd condition is 'true' or 'false', when the first condition is 'true', we call this type of situation 'don't cares', and use an 'X' to represent it (the 'X' means it can be either: true or false, or for binary: 1 or 0, correspondence is: true=1 / false=0, it doesn't change the final outcome):

true or X ----> TRUE


result = "east"

if (LCase (result) = "e" or LCase (result) = "east") {

first we do this (again assuming we start from the left):

is "east" = "e" ----> false

so, we now try the 2nd condition:

is "east" = "east" ----> TRUE

since this is a 2 condition 'or', quest probably knows that the final outcome is 'TRUE' (does the nested script/s) ...

but if it doesn't, it'd do a 3rd comparison to get the final outcome:

for ('false' or 'true') ----> TRUE, does the nested script(s)


result = "blah"

if (LCase (result) = "e" or LCase (result) = "east") {

first we do this (again assuming we start from the left):

is "blah" = "e" ----> false

so, we now try the 2nd condition:

is "blah" = "east" ----> false

since this is a 2 condition 'or', quest probably knows that the final outcome is 'FALSE' (skips over the nested script/s, goes to first 'else if' or next 'else if' or 'else') ...

but if it doesn't, it'd do a 3rd comparison to get the final outcome:

for ('false' or 'false') ----> FALSE, skips over the nested script/s, goes to first 'else if' or next 'else if' or 'else'


but we can make it more complex:

if (LCase (result) = "e" or LCase (result) = "east" or LCase (result) = "ea")

let's just show the entire operations for you, so you can see how it works:

(again assuming we start from the left)

result = "blah"

if (LCase (result) = "e" or LCase (result) = "east" or LCase (result) = "ea")

does "blah" = "e" ----> false_A
does "blah" = "east" ---> false_B
for ('false_A' or 'false_b') ----> false_D
does "blah" = "ea" ----> false_C
for ('false_D' or 'false_C') ----> FALSE


we can get (infinitely) more complicated/complex (though if you do understand it, all the rules and how it works, it's not actually more complex/complicated, it's just more busy work: just becomes more and more tedius, lol):

result = "blah"

if (((LCase (result) = "e") or (LCase (result) = "east")) or LCase (result) = "blah") and LCase (result) = "blah")

see if you can work this out for yourself... for a challenge... (assume you start from the left)

(if you can do this correctly, you understand this stuff now inside and out, lol)


this is getting into some heavy programming and symbolic logic (philosophy) type of stuff, so don't worry if you're compeltely confused, this is really advanced stuff. If you do want to understand it, feel free to ask for help, and I'll try to explain it better for you, lol.


@ JK and Richard:


you do NOT want to be doing the 'foreach' design, that's very inefficient, for what we're trying to do with the directional stuff.

I was just showing how'd it'd look if done that way/design, as that is what JK was trying to do in her code, acidentally, not knowing how to script in the conditionals correctly, or she was trying to do it through the lists as her design, but still had the syntax+design wrong on how to do it correctly.


there's definately a way to reference the Exits and their destination rooms for moving your player to/into them, but I'm not that familiar with the built-in stuff (Exits and the like)

Pixie can help, though I do remember seeing this:

'exit.to'

so maybe... something like this:

player.parent = exit.to
or
player.parent = NAME_OF_EXIT.to

or (if you prefer using the helper Function):

MoveObject (player, exit.to)
or
MoveObject (player, NAME_OF_EXIT.to)

though, you'd need to likely do some scripting to match your desired destination room with the correct 'exit.to / NAME_OF_EXIT.to' for it.

again, Pixie can help with this stuff, as I'm likely totally off, lol.


Now you're cooking! I'm getting it now.

See below:


This code is not quite correct.

msg ("The sky above is dominated by dark cloud... its not going to be friendly.</b>")
get input {
  if (LCase (result) = "e" or LCase (result) = "east") {
    msg ("&gt; "+result+"<br/>Against your better judgement, you decide to head east...")
    HandleSingleCommand ("e") // <---Insert command of your liking here. 
  }
  if (LCase (result) = "w" or LCase (result) = "west") {
    msg ("&gt; "+result+"<br/>Alternatively you go west.")
    HandleSingleCommand ("w")  // <---Insert command of your liking here. 
  }
  else {
    msg ("Wrong input. Try again.")
    //  ?->_ INQUIRY: What do we put here to make it loop? Do we call the function again?  _<-?
  }
}

This is what is printed to the screen. >You are in a room. You can go east or west. The sky above is dominated by dark cloud... its not going to be friendly. \> e Against your better judgement, you decide to head east... > >You are in a room to the east of the first room. You can go west. >\> w >You are in a room. You can go east or west. The sky above is dominated by dark cloud... its not going to be friendly. \> West Alternatively you go west. > >You are in a room to the west of the first room. You can go east. > >\> e > >You are in a room. You can go east or west. The sky above is dominated by dark cloud... its not going to be friendly. \> dilly dally Wrong input. Try again.

Thanks (again) HK!


(just to get this post to update... stupid edit post restrictions... argh)


"// ?->_ INQUIRY: What do we put here to make it loop? Do we call the function again? _<-? (Richard)"


depends on the parent of the scripting


examples of looping:

(with a check to end/escape the loop, so it's not an infinite loop and crashes quest, lol)


tail recursion looping (very easy to do/implement/simple-easy scrpting design, though if you got a long chain of multiple loopings and/or are using 'get input / show menu / ShowMenu / ask / Ask / etc stuff that gets-waits-for input' you're going to likely have errors, and will need to be much more creative in your design to get it working, lol):

(I'm not sure with quest and it's 'while' Function and/or how it'd be done, if it can be done, with iteration design in quest, but in for normal programming, tail recursion can always be done instead with iteration, which is much more efficient than doing tail recursion)

<function name="hi_function">
  msg ("hi")
  if (RandomChance (50)) {
    hi_function
  }
</function>

<object name="hi_object">
  <attr name="hi_script_attribute" type="script">
    msg ("hi")
    if (RandomChance (50)) {
      do (hi_object, "hi_script_attribute")
    }
  </attr>
</object>

using the 'while' Function for looping (if the 'while' Function is more efficient than tail recursion, then NEVER use tail recursion:

(I hope this works... I've not gotten around to testing the 'while' Function, yet... lol. There may be issues with it and/or just my code designs below)

<function name="hi_function">
  terminator_boolean_variable = false
  while (not terminator_boolean_variable) {
    msg ("hi")
    if (RandomChance (50)) {
      terminator_boolean_variable = true
    }
  }
</function>

<object name="hi_object">
  <attr name="hi_script_attribute" type="script">
    terminator_boolean_variable = false
    while (not terminator_boolean_variable) {
      msg ("hi")
      if (RandomChance (50)) {
        terminator_boolean_variable = true
      }
    }
  </attr>
</object>

if you need Arguments/Parameters and/or a return type, and you want/need to use an Object's Script Attribute, you can do so by using Delegates with it (and it'd be of: type="NAME_OF_DELEGATE", instead of: type="script", so it's not actual a 'Script Attribute' anymore):

if you're interested in learning how to use Delegates, let me know.


using iteration for looping in quest (if this can be done, NEVER use tail recursion):

I HAVE NO IDEA HOW THIS IS DONE (if it can even be done)


again, ask if you got any questions and/or need hlp with anything (or let me know if my code doesn't work, lol)


non-tail recursion is a completely different beast of looping... true recursion, which is very different from simple looping.

ht.tps://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursion
etc etc etc resources, but the khan academy seems like it'll explain recursion well (there's a 'next page or whatever it is called' button at the bottom, it has more pages)


Alright, HK! Thanks much!

I believe I've got it going on now! (I hope JK does too!)


This is a function named main_room_exits

The first room calls it in its After entering the roomscript.

Here we go:


msg ("The sky above is dominated by dark cloud... its not going to be friendly.</b>")
get input {
  if (LCase (result) = "e" or LCase (result) = "east") {
    msg ("&gt; "+result+"<br/>Against your better judgement, you decide to head east...")
    HandleSingleCommand ("e")
  }
  else if (LCase (result) = "w" or LCase (result) = "west") {
    msg ("&gt; "+result+"<br/>Alternatively you go west.")
    HandleSingleCommand ("w")
  }
  else {
    msg ("&gt; {result}<br/>Wrong input. Try again.")
    main_room_exits //    <--INQUIRY Is this tail recursion?
  }
}

Click to view STDOUT >You are in the first room. You can go east or west. The sky above is dominated by dark cloud... its not going to be friendly. >\>e Against your better judgement, you decide to head east... > >You are in a room to the east of the first room. You can go west. > > \>w > >You are in the first room. You can go east or west. The sky above is dominated by dark cloud... its not going to be friendly. >\> w Alternatively you go west. > >You are in a room to the west of the first room. You can go east. > >\> e > >You are in the first room. You can go east or west. The sky above is dominated by dark cloud... its not going to be friendly. >\>dilly dally Wrong input. Try again. The sky above is dominated by dark cloud... its not going to be friendly. >\> jump Wrong input. Try again. The sky above is dominated by dark cloud... its not going to be friendly. > \>e Against your better judgement, you decide to head east... > >You are in a room to the east of the first room. You can go west.
Click here to view the code for the entire, three room game


<!--Saved by Quest 5.6.6108.15891-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="tester2">
    <gameid>22411e75-0166-4656-a7a1-bf7c320fb92b</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>
    </game>
  <object name="the first room">
    <inherit name="editor_room" />
    <description type="script">
    </description>
    <usedefaultprefix type="boolean">false</usedefaultprefix>
    <enter type="script">
      main_room_exits
    </enter>
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <exit alias="east" to="room to the east of the first room">
      <inherit name="eastdirection" />
      <scenery type="boolean">false</scenery>
    </exit>
    <exit alias="west" to="room to the west of the first room">
      <inherit name="westdirection" />
      <scenery type="boolean">false</scenery>
    </exit>
  </object>
  <object name="room to the east of the first room">
    <inherit name="editor_room" />
    <exit alias="west" to="the first room">
      <inherit name="westdirection" />
    </exit>
  </object>
  <object name="room to the west of the first room">
    <inherit name="editor_room" />
    <exit alias="east" to="the first room">
      <inherit name="eastdirection" />
    </exit>
  </object>
  
  <function name="main_room_exits"><![CDATA[
    msg ("The sky above is dominated by dark cloud... its not going to be friendly.</b>")
    get input {
      if (LCase (result) = "e" or LCase (result) = "east") {
        msg ("&gt; "+result+"<br/>Against your better judgement, you decide to head east...")
        HandleSingleCommand ("e")
      }
      else if (LCase (result) = "w" or LCase (result) = "west") {
        msg ("&gt; "+result+"<br/>Alternatively you go west.")
        HandleSingleCommand ("w")
      }
      else {
        msg ("&gt; {result}<br/>Wrong input. Try again.")
        main_room_exits
      }
    }
  ]]></function>
</asl>

Umm...

I just used tail recursion; didn't I?

When I ended the function by calling the same function again in the else statement?

(Trying to read up on tail recursion online and going cross-eyed... They explain the basics of recursion, which I comprehend, in detail. Then all the sites flip to examples of tail recursion which are all written in programming languages I don't speak (yet).)


really irritating are these post editing restrictions... argh... come on.... update this post....


ya, 'tail recursion', in quest is the easiest way to do looping: you just call the function (using Functions as an example) again at the end of your Function's scripting (a bit more nuanced as, you can have mulitple 'ends' of scripting, which are not at the physical end-bottom of them, but hopefully you get the idea).

you can use tail-recursion (or if you don't like the use of the name of it, just think of it as looping instead) looping without any likely notice'able performance (slowness) issues. Don't worry of it being more 'inefficient', as I'm just talking about at micro/macro level or extremes of complex programs (doing ka zillions of operations, which isn't the case with game making with quest, lol).

here's an example:

<game name="example_game">
  <attr name="start" type="script">
    hi_function // in the GUI/Editor this is: run as script -> add new script -> 'scripts' section/category -> 'call function' Script -> Name: hi_function, (do NOT 'ADD' in any Parameters, for this case, as our 'hi_function' Function doesn't use any inputs)
  </attr>
</game>

<function name="hi_function">
  msg ("hi")
  if (RandomChance (50)) { // this 'if check' is just so it's not an infinite loop (which would crash quest)
    hi_function // calling the function again (looping it) (tail-recursion looping)
  }
</function>

don't worry about the example code they give in other programming languages:

as there's LOTS of scripting languages out there and (not too many) full-bore programming languages

people usually just specialize in one full-bore programming language, while being able to quickly learn (as you see more and more code, you can at least quickly read/understand whatever scripting language --- though it still takes some time to get familiar with their syntax structures and etc other stuff for writing them) whatever scripting language(s) as they need/want to use them, as scripting is scripting (you just got to learn that scripting language's syntax and etc stuff).


update my post... argh


here's my own older (and poor/bad/ineffient) example use of tail-recursion for the character creation system I'm still currently working on for my RPG (laughs):

(at the time, I was brain-dead, not realizing to simply make one dynamic function, via parameters, to handle the different actions I wanted, but instead I made multiple redundent functions, all doing the same thing... as I said, I was brain dead, at the time, lol)

ht.tp://textadventures.co.uk/forum/samples/topic/4988/character-creation-crude-code-and-sample-game


in general, visually this is how recursion works:

ht.tp://www.cs.princeton.edu/courses/archive/spr03/cs320/notes/7-1.pdf (anytime you do a function, it's like you created an Attribute/Object, called an 'Activation Record', which holds the data involved in that function, so recursion, while powerful for problem solving, due to its nature of operation, does a lot of functions, and thus a lot of activation records, which quickly eats of memory)

recursive_function_A
-> recursive_function_B
->-> recursive_function_C
->->-> recursive_function_d
->->->-> base_case reached, go back to previous recursive function (plugging in the base case / value) to finish it
<-<-<- recursive_function_d (use its value to plug into the previous recursive function to finsih it) // activation record (funct d is now done/finished/completed) destroyed (get back the memory it was using up)
<-<- recursive_function_C (use its value to plug into the previous recursive function to finish it) // activation record (funct c is now done/finished/completed) destroyed (get back the memory it was using up)
<- recursive_function_B (use its value to plug into the previous recursive function to finish it) // activation record (funct b is now done/finished/compelted) destroyed (get back the memory it was using up)
recursive_function_A // activation record (funct a is now done/finished/completed) destroyed (get back the memory it was using up) ------> final value (the "answer/result")

I wish I could find this as a drawing... with boxes... (as it's done in one of my school class programming books) but I've not come across it yet...

WOOT....

found a link that has it:

ht.tp://compsci.hunter.cuny.edu/~sweiss/course_materials/csci235/lecture_notes/chapter_02.pdf

just read on down a bit... you'll get to the box diagrams of how recursion works


Oh, okay: so it's cool to use tail recursion in Quest...

I misread your earlier post. I thought you said NEVER use tail recursion.

You actually said:

using iteration for looping in quest (if this can be done, NEVER use tail recursion):

I HAVE NO IDEA HOW THIS IS DONE (if it can even be done)

(Sometimes I'm skimming when I think I'm actually reading.)


Iteration...

Is that something like this?

<turnscript name="iteration">
      <enabled />
      <script>
        x = 5
        while (not x = 1) {
          x = x -1
          msg ("Just subtracted 1. Now x is "+x+".")
        }
      </script>
    </turnscript

When that script is enabled, you get this output in 1 turn:

> e
Against your better judgement, you decide to head east...

You are in a room to the east of the first room.
You can go west.
Just subtracted 1. Now x is 4.
Just subtracted 1. Now x is 3.
Just subtracted 1. Now x is 2.
Just subtracted 1. Now x is 1.


@Jennifer

Sorry, I didn't mean to take over your thread, but I'm addicted to learning how to do things in Quest!

(At least we pretty much kept on topic...)



I should have said it like this:

if there is noticable slow-down, and it's unbearable, then don't use tail-recursion, and instead use a less performance-hurting (less slow-down / more fast) design/operation, such as maybe the 'while' Function and/or however iteration would be done in quest (if it can be done)


I'm actually not even sure now how iteration for doing looping (instead of tail recursion) would be done in the full-bore programming languages now... (forgetting stuff... stupid summer break, lol)... or maybe I never knew how... meh, lol.


in general, this is iteration in quest:

foreach (item_variable, LIST) {
  // whatever
}

or

ht.tp://docs.textadventures.co.uk/quest/scripts/for.html

for (optionally_used_variable, MIN, MAX, optional_:_interval/skip/count-step_value) {
  // whatever
}

for examples:

for (var = 0, 1, 10, 1) {
  var = var + 1
}
msg (var)

// result/display: 10

-------

for (var = 0, 1, 10, 2) {
  var = var + 1
}
msg (var)

// result/display: 5

-----

for (var = 0, 1, 10, 10) { // or maybe its: for (var = 0, 1, 10, 9), meh
  var = var + 1
}
msg (var)

// result/display: 2

-----

for (var = 0, 1, 10, 100) {
  var = var + 1
}
msg (var)

// result/display: 1

----

for (var, 1, 10, 1) {
  // we don't have to use the Variable VARIABLE (my 'var' in these examples) at all, it's optional
  msg ("hi")
}

// result/output:

hi
hi
hi
hi
hi
hi
hi
hi
hi
hi
// I think that's 10 hi's, lol

---

so... I have no clue on how to implement a scripting's looping via using iteration.... (which can/should be done instead of tail-recursion). I'm totally baffled here.

How do we 'reset' the iteration (or either 'foreach' or 'for'), which would do the desired looping of it ??? I'm totally baffled (or blind...mind blind, lol), I'm totally stumped.

the 'while' is a type of 'loop', whereas 'iteration' is 'iteration' (not a 'loop')

in some of the other full-bore programming languages the also got:

a 'do-while' loop: it DOES the scripting at least once, but multiple times depends on the 'while' condition being met:

C++ : ht.tps://www.tutorialspoint.com/cplusplus/cpp_do_while_loop.htm

bool handled_boolean_variable = false;

do {
  cout << "hi";
  handled_boolean_variable = true;
} while (!handled_boolean_variable);

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

Java: ht.tps://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html

bool handled_boolean_variable = false;

do {
  System.out.println ("hi");
  handled_boolean_variable = true;
} while (!handled_boolean_variable);

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

Python: ht.tps://www.python.org/

(I don't know it that well yet)

(it's more, stream-lined: less typing, than C++/Java: no use of braces/brackets/etc)

errr.....

I guess the 'for' is considered as a 'loop', so iteration is 'looping' (or at least the 'for' iteration is considered as 'looping'), meh. I'm confusing myself too, lol.


HK,

See if you think I've got the basics of for figured out, please, sir:

http://textadventures.co.uk/forum/quest/topic/g8afycheqeydadaqkkc8pg/learning-or-trying-to-learn-how-to-use-for


yep, you got it correct, I messed up in my post above, as I get confused from quest's documentation of the use of 'for', in that the Variable is an Integer Variable and that it's defaulted to start at 0 (maybe you can still specify it's initial value: for (var = 8, min,max), not sure if this is built into quest or not for 'for', lol), thinking that 'for' in quest is different than it is in other languages, but it's not.


'for' enables you to specify the number of iterations/loops (whereas 'foreach' iterates through all the items in a list: the 'ListCount' determines the number of iterations/loops for the 'foreach'), along with also being able to do some fancy stuff with it, too.


you typed wrongly: LCASE (result)
there is no 'LCASE' Function in quest, hence the (unfortunately mis-leading/poor worded) error message
but, there is a 'LCase' Function, so to correct it, using this example of yours (fixed up):

Actually there is, kind of. Some functions are not case sensitive, and LCase is one, so it can be written LCASE. Eval is the same, and I do not know why. It is only the functions written in C#, but not all of them, for example msg is case sensitive.

you do NOT want to be doing the 'foreach' design, that's very inefficient, for what we're trying to do with the directional stuff.

foreachis often the easiest way, and when it goes to game development, creating code that is simple to write and to read is more efficient than writing complex code that you cannot understand when you look at it again in three months.

If you are worried about the speed your game is executed, the difference between for and foreach will be negligible. Quest probably runs about a dozen foreach every turn anyway as it updates the panes on the right, runs turn scripts, etc.


I was refering to:

get input {
  if (LCase (result) = "e" or LCase (result) = "east")  {
  } else if (LCase (result) = "w" or LCase (result) = "west")  {
  } else if (LCase (result) = "s" or LCase (result) = "south")  {
  } else if (LCase (result) = "n" or LCase (result) = "north")  {
  } else {
  }
}

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

vs (YUCK!):

east_list = split ("e;east", ";")
west_list = split ("w;west", ";")
north_list = split ("n;north", ";")
south_list = split ("s;south", ";")

handled = false

get input {
  foreach (string_variable, east_list) {
    if (LCase (result) = string_variable) {
      handled = true
    }
  }
  if (not handled) {
    foreach (string_variable, west_list) {
      if (LCase (result) = string_variable) {
        handled = true
      }
    }
  }
  if (not handled) {
    foreach (string_variable, north_list) {
      if (LCase (result) = string_variable) {
        handled = true
      }
    }
  }
  if (not handled) {
    foreach (string_variable, south_list) {
      if (LCase (result) = string_variable) {
        handled = true
      }
    }
  }
}

or, is the 'foreach' design, actually better? (doesn't seem like it can be, though I'm still a noob at knowing what algorithm designs are better/faster than others) (also, the 'foreach' design, is at least more work/typing, and maybe more confusing also for human understanding, I think than using the 'if' block design, but I could be wrong)


Or:

get input {
  switch(LCase(result)) {
    case ("e", "east") {
      msg("You go east")
    }
    case ("n", "north") {
      msg("You go north")
    }
    case ("w", "west") {
      msg("You go west")
    }
    case ("s", "south") {
      msg("You go south")
    }
    default {
      AskTheDirection
    }
  }
}

This would need to be done in a function, AskTheDirection, which gets called recursively if the player types in something else.

Or use a menu...


Didn't know you could do that in a switch -- have multiple instances separated by commas for a single case. That wasn't covered in the tutorial : )


Log in to post a reply.

Support

Forums