Programming Style Question

I have a few variables that will be equal to powers of 10, would it be more appropriate to hardcode these variables like this?

1
2
3
4
5
6
int Easy = 10;
int Medium = 100;
int Hard = 1000;
int Expert = 10000;
int Master = 100000;
int Heroic = 1000000;


or, like this?

1
2
3
4
5
6
7
8
9
10
const int numDifficulties = 6;
const int baseDifficulty = 10;
int compoundedDifficulty = 10;
int difficultyStorage[numDifficulties];

for ( unsigned int element = 0; element < numDifficulties; element++ )
{
    difficultyStorage[element] = compoundedDifficulty;
    compoundedDifficulty *= baseDifficulty;
}
Are these variables (ie: they will vary/change as the program runs)?

Or constants (ie: they will never change and will always be fixed values)?


If the latter, I would use an enum:
1
2
3
4
5
6
enum Difficulty
{
    Easy = 10,
    Medium = 100,
   // ... etc
};
Last edited on
They are constants.
Is it possible to have something like this?

 
enum Difficulty { Easy, Medium, //etc.. }; 


 
enum DifficultyLevel { Easy = 10, Medium = 100, //etc... 


In the same scope?
I would instead recommend a levelFromDifficulty function, and only have the first enum.
I'm getting a logic error, It doesn't matter what number I type in, the switch statement returns the default case, why is this occurring?

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>
using std::string;
using std::cout;
using std::cin;
using std::endl;

struct data {
int secretNumber;
int difficulty;
};

int getDifficultyFromUser();
int generateRandomNumber(const int& difficulty);
int getInput();

int main()
{
    data gameData;

    gameData.difficulty = getDifficultyFromUser();
    gameData.secretNumber = generateRandomNumber( gameData.difficulty );
    return 0;
}

int getDifficultyFromUser()
{
    cout << "Welcome to Number Guess Extreme!" << endl;
    cout << "Select your difficulty level! The harder the difficulty, the higher your possible score!" << endl;

    enum Difficulty
    {
        Easy = 10,
        Medium = 100,
        Hard = 1000,
        Expert = 10000,
        Master = 100000,
        Heroic = 1000000
    };

    enum Choice
    {
        EasyDifficulty = 1,
        MediumDifficulty,
        HardDifficulty,
        ExpertDifficulty,
        MasterDifficulty,
        HeroicDifficulty
    };

    cout << "1) Easy - " << Easy << endl;
    cout << "2) Medium - " << Medium << endl;
    cout << "3) Hard - " << Hard<< endl;
    cout << "4) Expert - " << Expert << endl;
    cout << "5) Master - " << Master << endl;
    cout << "6) Heroic - " << Heroic << endl;

    while ( true )
    {
        switch ( getInput() )
        {
            case EasyDifficulty: return Easy;
                    break;
            case MediumDifficulty: return Medium;
                    break;
            case HardDifficulty: return Hard;
                    break;
            case ExpertDifficulty: return Expert;
                    break;
            case MasterDifficulty: return Master;
                    break;
            case HeroicDifficulty: return Heroic;
                    break;
            default: cout << "Unrecognized entry." << endl;
        }
    }
}

int generateRandomNumber(const int& difficulty)
{

}

int getInput()
{
    cout << "> ";
    string userInput;
    int extractedInput;

    while ( true )
    {
        getline(cin, userInput);

        if ( isdigit(userInput[0]) )
        {
            extractedInput = userInput[0];
            return extractedInput;
        }
        else
        {
            cout << "Invalid, try again." << endl;
        }
    }

}
Last edited on
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
63
64
65
66
#include <iostream>
#include <type_traits>
#include <string>
#include <cctype>
#include <algorithm>
#include <iterator>

enum difficulty : unsigned int { EASY, MEDIUM, HARD, EXPERT, MASTER, HEROIC };

template < unsigned int N > struct level : std::integral_constant< unsigned int, level<N-1>::value * 10 > {};

template <> struct level<EASY> : std::integral_constant< unsigned int, 10 > {} ;

unsigned int level_of( difficulty d )
{
    switch(d)
    {
        case EASY: return level<EASY>::value ;
        case MEDIUM: return level<MEDIUM>::value ;
        case HARD: return level<HARD>::value ;
        case EXPERT: return level<EXPERT>::value ;
        case MASTER: return level<MASTER>::value ;
        default: return level<HEROIC>::value ;
    }
}

static constexpr const char* const difficulty_str[] = { "EASY", "MEDIUM", "HARD", "EXPERT", "MASTER", "HEROIC" };

std::ostream& operator<< ( std::ostream& stm, difficulty d )
{ return stm << difficulty_str[d] << '(' << level_of(d) << ')' ; }

std::istream& operator>> ( std::istream& stm, difficulty& d )
{
    unsigned int number ;
    if( stm >> number )
    {
        if( number <= HEROIC ) d = difficulty(number) ;
        else stm.setstate( std::ios::failbit ) ;
    }
    else
    {
        stm.clear() ;
        std::string str ;
        if( stm >> str )
        {
            for( char& c : str ) c = std::toupper(c) ;
            const auto iter = std::find( std::begin(difficulty_str), std::end(difficulty_str), str ) ;
            if( iter != std::end(difficulty_str) ) d = difficulty( iter - std::begin(difficulty_str) ) ;
            else stm.setstate( std::ios::failbit ) ;
        }
    }
    return stm ;
}

int main()
{
    std::cout << EXPERT << '\n' ; // EXPERT(10000)

    difficulty d ;
    if( std::cin >> d ) std::cout << d << '\n' ;
    if( std::cin >> d ) std::cout << d << '\n' ;
    if( std::cin >> d ) std::cout << d << '\n' ;
    
    if( std::cin >> d ) std::cout << d << '\n' ;
    else std::cerr << "*** error ***\n" ;
}

http://coliru.stacked-crooked.com/a/4ba3d5f17b6c99c4
KISS:
1
2
3
4
5
6
const int Easy = 10;
const int Medium = 100;
const int Hard = 1000;
const int Expert = 10000;
const int Master = 100000;
const int Heroic = 1000000;

or if the multiple matters:
1
2
3
4
5
6
7
const in multiple = 10;
const int Easy = multiple;
const int Medium = Easy*multiple;
const int Hard = Medium * multiple;
const int Expert = Hard * multiple;
const int Master = Expert * multiple;
const int Heroic = Master * multiple;

Think about whether you are likely to change these and if so, then how? For example , you may decide that each level should be twice the previous one. In that case my second example makes changing it simple.

But really, with 6 values changing it to anything will be pretty easy. A much more important question to ask is whether they should be constants or variables. Will they ever change while the game is running? Will then need to be read from a config file? if either of those are likely then they should be variables.
KISS: Keep It Simple, Stupid. (US Navy, 1960)
1
2
3
const int blah1 = etc.

void foo( int hope_that_this_is_one_of_those_blahs ) ;


TISS: Type-safe Is Simple, Stupid. (C++, 1985)
1
2
3
enum blah { blah1 = etc.

void foo( blah this_is_blah ) ;
i write in 'e' for easier reading
1
2
3
4
5
6
const int Easy = 1e1;
const int Medium = 1e2;
const int Hard = 1e3;
const int Expert = 1e4;
const int Master = 1e5;
const int Heroic = 1e6;
Jlborges, that looks fantastic but i literally have no idea what half of those functions do lol, NOW I feel like a beginner :P. and Anup, I like that!
The type traits library doesn't work for me.
enum difficulty : unsigned int { EASY, MEDIUM, HARD, EXPERT, MASTER, HEROIC };

this gives me an error
> The type traits library doesn't work for me.

Requires C++11.

Simplified, legacy C++ version:

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
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>

enum difficulty  { EASY, MEDIUM, HARD, EXPERT, MASTER, HEROIC };
const char* const difficulty_str[] = { "EASY", "MEDIUM", "HARD", "EXPERT", "MASTER", "HEROIC" };
const int difficulty_level[] = { 10, 100, 1000, 10000, 100000, 1000000 };

int level_of( difficulty d ) { return difficulty_level[d] ; }

std::ostream& operator<< ( std::ostream& stm, difficulty d )
{ return stm << difficulty_str[d] << '(' << level_of(d) << ')' ; }

std::istream& operator>> ( std::istream& stm, difficulty& d )
{
    unsigned int number ;
    if( stm >> number )
    {
        if( number <= HEROIC ) d = difficulty(number) ;
        else stm.setstate( std::ios::failbit ) ;
    }
    else
    {
        stm.clear() ;
        std::string str ;
        if( stm >> str )
        {
            for( std::size_t i = 0 ; i < str.size() ; ++i ) str[i] = std::toupper( str[i] ) ;
            
            const char* const* const iter = std::find( difficulty_str, difficulty_str+HEROIC, str ) ;
            if( iter != (difficulty_str+HEROIC) ) d = difficulty( iter - difficulty_str ) ;
            else stm.setstate( std::ios::failbit ) ;
        }
    }
    return stm ;
}

int main()
{
    std::cout << EXPERT << '\n' ; // EXPERT(10000)

    difficulty d ;
    if( std::cin >> d ) std::cout << d << '\n' ;
    if( std::cin >> d ) std::cout << d << '\n' ;
    if( std::cin >> d ) std::cout << d << '\n' ;

    if( std::cin >> d ) std::cout << d << '\n' ;
    else std::cerr << "*** error ***\n" ;
}

http://coliru.stacked-crooked.com/a/c6fd45e0e2b8162a
1
2
std::ostream& operator<< ( std::ostream& stm, difficulty d )
{ return stm << difficulty_str[d] << '(' << level_of(d) << ')' ; }


This bit is VERY interesting to me but also new, what is happening here?
difficulty d when implicitly converted to an integer type will have a value in the range 0...5
(EASY==0, MEDIUM==1 etc.)

difficulty_str[d] - look up in the array containing the corresponding string descriptions.

level_of(d) - call the function, which in turn looks up in the level values array and returns the result.
Topic archived. No new replies allowed.