Home > Back-end >  Is there a better way to write these If-Statements?
Is there a better way to write these If-Statements?

Time:06-29

I'm building a Random Character Generator in C , and I have around 12 large blocks of if statements, like this:

int wisdom = rand() % 18;

cout << "\n";

if (wisdom == 0 || wisdom == 1) {

    cout << "Wisdom Score: 1\n";
    cout << "Modifier: -5\n";

} else if (wisdom == 2 || wisdom == 3) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier: -4\n";

} else if (wisdom == 4 || wisdom == 5) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier: -3\n";

} else if (wisdom == 6 || wisdom == 7) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier: -2\n";

} else if (wisdom == 8 || wisdom == 9) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier: -1\n";

} else if (wisdom == 10 || wisdom == 11) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier:  0\n";

} else if (wisdom == 12 || wisdom == 13) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier:  1\n";

} else if (wisdom == 14 || wisdom == 15) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier:  2\n";

} else if (wisdom == 16 || wisdom == 17) {

    cout << "Wisdom Score: " << wisdom << "\n";
    cout << "Modifier:  3\n";

} else {

    cout << "Wisdom Score: 18\n";
    cout << "Modifier:  4\n"; 

}

I'm wondering, is there a better way to write this? Perhaps some type of function?

CodePudding user response:

The better way is to not write chained ifs at all, but instead compute the value you care about.

if (wisdom == 0) wisdom = 1; // Handle edge case treating 0 as 1
int modifier = wisdom / 2 - 5;

cout << "Wisdom Score: " << wisdom << '\n';
cout << "Modifier: " << modifier << '\n';

Note that your calculation of int wisdom = rand() % 18; cannot produce 18 (and does produce 0, which you don't want), so you probably want to change it to:

int wisdom = rand() % 18   1;  // Result guaranteed to be 1-18 inclusive

allowing you to simplify the code by removing the if (wisdom == 0) wisdom = 1; edge case.

As another answer has already noted, rand is typically considered a bad API, so unless you're okay with biased results (e.g. slightly more low rolls than high rolls), you'll want to use modern C PRNG APIs (they're a little more work to set up, but trivial to use once you've done so, and they should avoid bias issues).

CodePudding user response:

Use the fact that the division of 2 integral values results in the trucation of the result:

...
int modifier = (wisdom / 2) - 5;

CodePudding user response:

You don't need any conditionals. Also, don't use rand() %.

std::mt19937 mt(42); // seed
auto const wisdom = std::uniform_int_distribution<int>(0,18)(mt);
auto const score = wisdom   !wisdom;
auto const mod = wisdom / 2 - 5;

std::cout << "Wisdom Score: " << score << "\n";
std::cout << "Modifier: " << mod << "\n";

This assumes it is intentional that you have a double chance of wisdom score 1 proccing compared to other scores. If not change the lower bound in the std::uniform_int_distribution construction from 1 to 0.

  •  Tags:  
  • c
  • Related