Is this cumbersome?

I am creating a elaborate number guessing game that will have special abilities, highscores, and numerous other additions to the basic number guessing game to make it more enjoyable. I'm currently setting the difficulty range of the numbers, is this code cumbersome thus far?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
using std::string;
using std::cout;
using std::endl;
using std::cin;


const int numDiff = 6;
string difficultyStr[numDiff] = { "Easy", "Medium", "Hard", "Expert", "Master", "Insane" };
enum difficulty { Easy, Medium, Hard, Expert, Master, Insane };
enum difficultyLevel { EasyD = 10, MediumD = 100, HardD = 1000, ExpertD = 10000, MasterD = 100000, InsaneD = 1000000 };

difficultyLevel get_difficulty()
{
    const char EasyChoice = 'A';
    const char MediumChoice = 'B';
    const char HardChoice = 'C';
    const char ExpertChoice = 'D';
    const char MasterChoice = 'E';
    const char InsaneChoice = 'F';

    cout << "Choose a difficulty!\n" << endl;
    cout << EasyChoice << ") " << difficultyStr[Easy] << " - " << EasyD << endl;
    cout << MediumChoice << ") " <<difficultyStr[Medium] << " - " << MediumD << endl;
    cout << HardChoice << ") "  << difficultyStr[Hard] << " - " << HardD << endl;
    cout << ExpertChoice << ") "  << difficultyStr[Expert] << " - " << ExpertD << endl;
    cout << MasterChoice << ") "  << difficultyStr[Master] << " - " << MasterD << endl;
    cout << InsaneChoice << ") "  << difficultyStr[Insane] << " - " << InsaneD << endl;
    
    bool decisionMade = false;
    string takeInput;
    char extractInput;
    
    while ( !decisionMade )
    {
        getline(cin, takeInput);
        extractInput = toupper(takeInput[0]);
        switch ( extractInput )
        {
            case EasyChoice: return EasyD;
                break;
            case MediumChoice: return MediumD;
                break;
            case HardChoice: return HardD;
                break;
            case ExpertChoice: return ExpertD;
                break;
            case MasterChoice: return MasterD;
                break;
            case InsaneChoice: return InsaneD;
                break;
            default: cout << "Unrecognized, try again." << endl;
        }
    }
}


int main()
{
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <cctype>
#include <stdexcept>

enum difficulty { Easy, Medium, Hard, Expert, Master, Insane };
constexpr int NUM_DIFF = Insane + 1 ;
const std::string difficulty_str[NUM_DIFF] = { "Easy", "Medium", "Hard", "Expert", "Master", "Insane" };
enum difficulty_level { EasyD = 10, MediumD = 100, HardD = 1000, ExpertD = 10000, MasterD = 100000, InsaneD = 1000000 };

difficulty_level get_difficulty()
{
    static constexpr difficulty_level level[NUM_DIFF] = { EasyD, MediumD, HardD, ExpertD, MasterD, InsaneD };
    static const std::string choices = "ABCDEF" ;

    std::cout << "Choose a difficulty!\n" ;
    for( int i = 0 ; i < NUM_DIFF ; ++i )
        std::cout << choices[i] << ") " << difficulty_str[i] << " - " << level[i] << '\n' ;

    char input;
    if( std::cin >> input )
    {
        std::size_t i ;
        if( ( i = choices.find( std::toupper(input) ) ) != std::string::npos ) return level[i] ;

        std::cout << "\nUnrecognized choice, try again.\n" ;
        std::cin.ignore( 1000, '\n' ) ; // empty input buffer (optional)
        return get_difficulty() ; // try again
    }

    else throw std::runtime_error( "eof on stdin" ) ;
}
What does static constexpr do exactly? I haven't had much exposure to that. Also, doesn't returning a function, make that function recursive, and isn't that bad programming style?
> What does static constexpr do exactly?

In this case, static specifies a static storage duration;

static const std::string choices = "ABCDEF" ; // line 14
The object choices is initialised when control reaches line 14 for the first time.
When the function is called again, the same object is reused.

constexpr (C++11): the const object level must be initialised at compile-time.
In legacy C++, use the const keyword instead.


> isn't that bad programming style?

IMO, a programming style that minimises the use of loops is a good programming style. Code that uses standard algorithms has a much higher chance of being correct the first time than code that uses loops instead.
(I've made an exception for the C++11 range-based loop; it is a looping construct that is fairly immune from errors).

Recursive algorithms, while being programmer efficient, may not be as machine efficient as iterative algorithms if the compiler is unable to optimise away the recursive call. However, in a function which blocks for user input, the machine efficiency concern becomes utterly irrelevant; a million instructions can be executed in the time it takes for the user to enter a single character.
Thanks for that explanation!
Is size_t same as unsigned int, but basically just a sign to the programmer that variable is supposed to be used for iterating a array?
> Is size_t same as unsigned int

std::size_t is an alias for an (implementation-defined) unsigned integer type. It may or may not be an unsigned int.

See: http://en.cppreference.com/w/cpp/types/size_t
Topic archived. No new replies allowed.