Help understanding switch statements.

Hello, 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?)


Hello.

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).


Switch 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.


As 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)


Switch 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.


PS

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.


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.

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:

  1. Giving switch or case 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")
  2. 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)

Using 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.


Get Input is not needed to use Switch.
BUT, you do need to check something.


Log in to post a reply.

Support

Forums