0

我如何解释在“选择你自己的冒险”游戏中如何以及何时使用 if 语句与 switch 语句?

游戏的基本结构是,如果你输入某个答案,它就会改变游戏的流程或方向。我通常使用带有函数的 if 语句,但这是最有效和最简单的教学方法吗?

谢谢!

编辑:哇,非常感谢您提供这么多很棒的答案!最后一点:如果你是一个 13 岁的孩子,在没有任何编程知识的情况下试图掌握这个概念你会如何尝试去理解它?说真的,非常感谢您的帮助!!

4

6 回答 6

3

有(给予或接受)五种不同的解决方案来解决“我收到了这个意见,我现在该怎么办”。

  1. if/else if/else ...链。优点是您可以使用任何可以制成trueor的表达式false。缺点是当你有一个长链时它会变得非常混乱。
  2. Switch - 非常适合“有很多几乎相似的事情要做”。缺点是case标签必须是整数值(或char值,但不是字符串、浮点值等)。
  3. 使长 if/else 变得更简单的表格if(table[index].something) ...
  4. 函数指针——一种表指针变体——存储一个指向函数的指针,如果你朝那个方向移动,它会做你想做的任何事情。
  5. 使用虚函数的对象。同样,table解决方案的一个变体,但不是存储函数指针,而是存储具有一些成员函数的对象,我们可以使用这些成员函数来“做任何你需要做的事情”。

在这种情况下,正确的解决方案可能是后三个之一的组合/变体——至少在我看来。

于 2013-06-14T00:20:21.683 回答
2

在这种情况下,您描述的if语句几乎是您的最佳选择,因为代码需要将用户提供的答案与一些预定义的选项进行比较。

这些选项很可能是字符串。switchC++ 中的语句不能对字符串起作用。因此,一系列if语句可能会更简单。

switch答案仅包含数字或单个字符时,可以使用语句。

例如,游戏主菜单的代码片段可能如下所示:

控制台输出:

Please select an action:
1) Start a new game.
2) Go to options screen.
3) Quit game.

代码:

int userChoice = getUserInput();

switch(userChoice){
case START_NEW_GAME: //1
    startGame(); break;
case OPTIONS: //2
    showOptions(); break;
case QUIT: //3
    exit(); break;
}
于 2013-06-13T23:43:32.040 回答
2

switch在识别数值或序数值的情况时使用语句。

switch (number)
{
    case 1: DoSomething();
        break;

    case 2: DoSomethingElse();
        break;
}

使用if,elseifelse用于更复杂的条件,例如数值范围。

if (number > 0 && number <= 100)
{
   DoSomething();
}
else if (number > 100 && number <= 1000)
{
   DoSomethingElse()
}
else
{
   NotifyOutOfRange();
}
于 2013-06-13T23:38:45.760 回答
1

switch陈述是为了速度。这就是为什么它们只是数字。编译器将尝试为非稀疏(即连续)值范围创建查找表,这可以在代码不断执行时显着提高性能。这是因为它只需要对一个连续的范围进行 1 次比较来确定要执行哪一段代码。

switch语句可能会导致难以发现的错误,因为在每个语句的末尾case您需要指定 a break,否则执行将落到下一个case.

if//语句用于更一般的用途else if如果同一个值进行多次比较else,它们通常比等效switch语句慢。但是,如果该语句链执行的次数不多且链不是那么长,则性能改进可以忽略不计。if

对于更一般的用法,if是要走的路。在 CYOAG 中,您将不需要速度。游戏中最慢的部分是用户。

向一个 13 岁的孩子解释这一点:

如果您认为您将一次对单个整数(整数)值执行超过 1,000,000 次或更多次的比较,并且您需要尽快完成,请使用switch语句。否则,无所谓。使用时要小心 a ,因为如果每个结尾switch都没有 a ,你会摸不着头脑想弄清楚刚刚发生了什么?当执行两个或多个s 时。breakcasecase

于 2013-06-14T02:43:23.377 回答
0

好吧,您不能真正将字符串放入switch/ case。这给你留下了if. 或者您需要实现读取字符串的解析器,将它们映射到某种enum类型,然后enumswitch/中使用 say case

然而,更好(更可扩展)的方法是使用函数回调映射。

像这样的东西:

#include <map>
#include <string>
#include <iostream>

typedef void(*ActionCallback)();
typedef std::map<std::string, ActionCallback> ActionMap;
static bool running = true;

void leftAction(){
    std::cout << "\"left\" entered" << std::endl;
}

void rightAction(){
    std::cout << "\"right\" entered" << std::endl;
}

void quitAction(){
    std::cout << "game terminated" << std::endl;
    running = false;
}

int main(int argc, char** argv){
    ActionMap actionMap;
    actionMap["left"] = leftAction;
    actionMap["right"] = leftAction;
    actionMap["quit"] = quitAction;

    while(running){
        std::string command;
        std::cout << "enter command. Enter \"quit\" to close" << std::endl;
        std::cin >> command;

        ActionMap::iterator found = actionMap.find(command);
        if (found == actionMap.end())
            std::cout << "unknown command " << command << std::endl;
        else
            (*found->second)();
    }
    return 0;
}

这种方法的最大优点是您可以在运行时更改命令。添加新命令、删除它们等。您甚至可以更进一步,添加 lisp/python/lua 绑定并使其更具可扩展性。

于 2013-06-14T01:00:39.590 回答
0

如果您有太多“else if”语句,您可以使用 switch 语句 :)

更严重的是,如果一个玩家有很多不同的选择(比如从 2​​6 个不同的选项(az)中选择,那么切换就是要走的路)。

于 2013-06-13T23:39:40.153 回答