Home > Mobile >  Is there any way to have switch that checks 2 parameters?
Is there any way to have switch that checks 2 parameters?

Time:05-19

I am working on my school project and was wondering If I could make my code look cleaner by replacing:

switch (screen) {
    case 0:
    switch (language) {
        case 0:
            std::cout << "1 - Start new game" << std::endl;
            std::cout << "2 - Load save" << std::endl;
            std::cout << "2 - Hall of fame" << std::endl;
            std::cout << "3 - Select language" << std::endl;
            std::cout << "h - Help" << std::endl;
            break;
        case 1:
            std::cout << "1 - Zacznij nową grę" << std::endl;
            std::cout << "2 - Wczytaj grę" << std::endl;
            std::cout << "2 - sala sławy" << std::endl;
            std::cout << "3 - wybierz język" << std::endl;
            std::cout << "h - pomoc" << std::endl;
            break;

    }
    break;
}

by something like this:

switch (screen)(language) {
    case 0 0:
            std::cout << "1 - Start new game" << std::endl;
            std::cout << "2 - Load save" << std::endl;
            std::cout << "2 - Hall of fame" << std::endl;
            std::cout << "3 - Select language" << std::endl;
            std::cout << "h - Help" << std::endl;
            break;
    case 0 1:
            std::cout << "1 - Zacznij nową grę" << std::endl;
            std::cout << "2 - Wczytaj grę" << std::endl;
            std::cout << "2 - sala sławy" << std::endl;
            std::cout << "3 - wybierz język" << std::endl;
            std::cout << "h - pomoc" << std::endl;
            break;

    }

Is there any construction like this in c ? I tried googling it, but no matter the phrasing I couldn't find anything.

CodePudding user response:

I wouldn't recommend it for this sort of thing - there are better ways than using switch for localisation or for menus - and code should be doing one thing, but to combine two values into one you can use bitwise operations that shift by whole nibbles then hex literals in the cases:

switch ((screen << 4) | language) {
    case 0x00:
        std::cout << "1 - Start new game" << std::endl;
        std::cout << "2 - Load save" << std::endl;
        std::cout << "2 - Hall of fame" << std::endl;
        std::cout << "3 - Select language" << std::endl;
        std::cout << "h - Help" << std::endl;
        break;
    case 0x01:
        std::cout << "1 - Zacznij nową grę" << std::endl;
        std::cout << "2 - Wczytaj grę" << std::endl;
        std::cout << "2 - sala sławy" << std::endl;
        std::cout << "3 - wybierz język" << std::endl;
        std::cout << "h - pomoc" << std::endl;
        break;
    case 0x10:
        // screen 1 language 0
        break;
    case 0x11:
        // screen 1 language 1
        break;

    }
    break;
}

I wouldn't use this in an application, but have used it for lower level stuff, for example to combine the outputs of multiple rotary encoder sensor bits and previous states to determine direction of rotation.

CodePudding user response:

As long as you can write a constexpr function from your inputs to an integral type, you can switch over multiple things.

constexpr int screen_and_language(int screen, int language) {
    return (screen << 4) | language;
}

switch screen_and_language(screen, language) {
    case screen_and_language(0, 0):
            std::cout << "1 - Start new game" << std::endl;
            std::cout << "2 - Load save" << std::endl;
            std::cout << "2 - Hall of fame" << std::endl;
            std::cout << "3 - Select language" << std::endl;
            std::cout << "h - Help" << std::endl;
            break;
    case screen_and_language(0, 1):
            std::cout << "1 - Zacznij nową grę" << std::endl;
            std::cout << "2 - Wczytaj grę" << std::endl;
            std::cout << "2 - sala sławy" << std::endl;
            std::cout << "3 - wybierz język" << std::endl;
            std::cout << "h - pomoc" << std::endl;
            break;
}

CodePudding user response:

Not directly but you can use a single variable that would hold all the semantic you need.

For example:

Value Meaning
0 screen==0 && language==0
1 screen==0 && language==1
2 screen==1 && language==0
3 screen==1 && language==1

Of course, you can use an enumeration instead so that it would be more explicit.

Which would then become:

enum MenuSettings {SL_00, SL_01, SL_10, SL_11};
Value Meaning
SL_00 screen==0 && language==0
SL_01 screen==0 && language==1
SL_10 screen==1 && language==0
SL_11 screen==1 && language==1

The downside with this workaround is that the enum would be pretty long if you have a lot of languages or/and a lot of screens to handle.

  • Related