Help understanding switch statements.

Sara377544
17 Jul 2021, 00:26Hello, sorry to bother everyone again with my dumb questions. I need a bit of help understand how switch statements work. Now, I know theres a tutorial about it in quest tutorial and I followed it, but only understood it when it works with showmenu.
But I want one that doesn't rely on shortmenu, but rather just a substitute on ifs.
For example:
If player is in room x
else if player is in room y
else if player is in room z
else
I understand how these work with if, but not sure how to program them with switch. For anyone wondering i program with downloadable version.
Also, is it possible (and ok) to put a switch inside a switch? Like for example, as a result of 1 switch leading to a script that will lead to another switch (kind of nested inside the first?)
K.V.
17 Jul 2021, 01:14Hello.
An if
statement works similarly to a switch
statement.
Using if
:
if (game.pov.parent = room x) {
// Do something
}
else if (game.pov.parent = room y) {
// Do something different
}
else if (game.pov.parent = room z) {
// Do something completely different
}
else {
// Do something, or do nothing; do whatever
}
The same thing using switch
:
switch (game.pov.parent) {
case (room x) {
// Do something
}
case (room y) {
// Do something different
}
case (room z) {
// Do something completely different
}
default {
// Do something, or do nothing; do whatever
}
}
Also, is it possible (and ok) to put a switch inside a switch? Like for example, as a result of 1 switch leading to a script that will lead to another switch (kind of nested inside the first?)
Yep. Just add it where you want it.
Most people use if
statements more often than switch
statements, unless they're only checking the value of one thing over and over, as in this example (game.pov.parent
).
jmnevil54
17 Jul 2021, 01:56Switch statements will work as a stand alone, but not as an if replacement entirely.
Here is an example. I typed this in the room description.
msg ("Please type 1, 2, 3, or 4.")
get input {
switch (result) {
case (1) {
msg ("You typed 1.")
}
case (2) {
msg ("You typed 2.")
}
case (3) {
msg ("You typed 3.")
}
case (4) {
msg ("You typed 4.")
}
default {
msg ("No. You typed a message!")
}
}
}
Switch statements always need input. If they don't have input, they will fail. At least, that's how it works with Quest.
K.V.
17 Jul 2021, 13:59As an if
statement:
msg ("Please type 1, 2, 3, or 4.")
get input {
result = Trim(result)
if (result = "1") {
msg ("You typed 1.")
}
else if (result = "2") {
msg ("You typed 2.")
}
else if (result = "3") {
msg ("You typed 3.")
}
else if (result = "4") {
msg ("You typed 4.")
}
else{
msg ("No. You typed something other than 1, 2, 3, or 4.")
}
}
:o)
K.V.
17 Jul 2021, 14:11Switch statements always need input. If they don't have input, they will fail.
Correct.
A switch
statement requires a parameter. The purpose of a switch
statement is to check if its parameter matches a case
.
switch ("a") {
case ("a") {
msg ("MATCH!")
}
default {
msg ("NO MATCH!")
}
}
If you were to try to run that without a parameter, it would throw an error:
switch () {
case ("a") {
msg ("MATCH!")
}
default {
msg ("NO MATCH!")
}
}
Error running script: Error compiling expression '': SyntaxError: Unexpected end of fileLine: 1, Column: 1
Also, just for completion's sake, you don't need to include a default
.
It is wise to include a default
when dealing with player input, though -- to make sure something prints in response to the player's input.
K.V.
17 Jul 2021, 14:48PS
I just learned something about Quest from jmne's code.
In that code,result
is a string. It is the player's input.
She is using integers rather than strings in each case
parameter, but Quest actually matches my input of "2"
to the integer 2
.
I didn't even know Quest would do that. If you try to compare a string to an integer in any other bit of code in Quest, it will throw an error and mess everything up.
This seems cool in her example, but we will develop bad habits if we don't learn to code things properly. In practice, we should always make sure our case
parameter is the same type as our switch
parameter.
Even if it works in Quest (which it does), it does not work in Javascript:
let result = '2';
switch(result){
case 2:
console.log("The integer 2")
break;
case "2":
console.log("The string '2'")
break;
default:
console.log("DEFAULT")
}
OUTPUT:
The string '2'
To be sure we learn good coding habits, we should write jmne's code like this:
msg ("Please type 1, 2, 3, or 4.")
get input {
// Removing any leading or trailing whitespace from 'result' with Trim()
result = Trim (result)
switch (result) {
case ("1") {
msg ("You typed 1.")
}
case ("2") {
msg ("You typed 2.")
}
case ("3") {
msg ("You typed 3.")
}
case ("4") {
msg ("You typed 4.")
}
default {
// Provide a vague, yet specific response.
// (It might not be a message. The player might enter 5, or even something like "one".)
msg ("No. You typed something other than 1, 2, 3, or 4.")
}
}
}
It's good code in Quest jmne!
So, I'm not saying you were wrong. I'm just saying it's better to learn good coding habits that will apply everywhere, which is something mrangel has gone through great lengths to teach me.
EDIT
I'm not even saying anyone should change this in any existing Quest code. I'm just saying we should all learn good coding habits henceforth. :o)
I don't know if someone tweaked switch
in Quest, or if it works this way in C# by default. All I know is learning it this way will cause you problems in the future when you end up coding in Javascript, and you will probably end up coding in Javascript if you continue learning to code.
mrangel
17 Jul 2021, 22:28I didn't even know Quest would do that. If you try to compare a string to an integer in any other bit of code in Quest, it will throw an error and mess everything up.
I ran into this before.
The reason is that the switch statement is backed by a hashmap - essentially a scriptdictionary, but an order of magnitude more efficient. If the values in the case
statements are constants or constant expressions, they are evaluated once when the code is first compiled. Afterwards, the parameter to switch
is essentially used as a dictionary key to look up the right piece of code to run.
On the plus side, this means you don't have to worry about type checking, as (like dictionary keys) the values passed to switch and case are converted to strings before comparing. (Note that this isn't quite the same as Quest's usual type conversion. For example, switch/case will convert an object to a string containing its name.
The cons of this approach:
- Giving
switch
orcase
a list or dictionary parameter will not do what you expect. (I can't remember what it actually does, but I vaguely recall going over the code and thinking "wow, that's dumb") case (null)
can cause odd crashes, sometimes when it isn't even being run (because IASL does fancy stuff in the background, trying to generate the lookup table before it's needed so it can be more efficient)

Sara377544
18 Jul 2021, 03:22Using K.v's first code worked (and will help me in some scenarios because I've made a lot of timers that will print different messages in different rooms, and it will get easier to edit in the future if they're all neat in switch rather than gigantic lines of ifs.
I am confused a bit since you said it always needs input but in this scenario does it need an input? Or is the player location already an input? Is it bad coding to use the room switch idea? Just a bit confused sorry, english is not my first language.

DarkLizerd
18 Jul 2021, 15:27Get Input is not needed to use Switch.
BUT, you do need to check something.