2

I got a small program where in the end, the program asks the user if he/she wants to roll dice to win an extra 15% off their initial check, but my if statement is not recognizing that if the user rolls a 6, they win the discount. When the dice eventually rolls a 6, it still reads as a fail and tells the user to pay the full amount. How can I work around this?

My class:

class roll
{
private:
    int high;
public:
    roll(int high = 6)
    {
        this->high = high;
    }

    ~roll()
    {

    }

    int rolled(int amt = 1)
    {
        int done = 0;

        for (size_t x = 0; x < amt; x++)
        {
            done += rand() % high + 1;
        }
        return done;
    }

};

My if statement:

  cout << "Would you like to play a dice game for a discount? Y/N: " << endl;
            cin >> res;
            if (res == 'Y' || res == 'y')
            {
                srand(time(static_cast<unsigned>(0)));
                roll one;
                cout << one.rolled() << endl;
                if (one.rolled() == 6)
                {
                    cout << "Congratulations!  You won 15% off your meal!!!" << endl;
                    prize = grandtot - (grandtot * .15);
                    cout << "Your final total will be $" << prize << endl;
                }
                else
                {
                    cout << "Sorry, you did not win, pay the original amount!" << endl;
                }
            }
            else
            {
                cout << "Thank you, pay the original amount and have a nice day!" << endl;
            }
  • 3
    Remember that `rolled` will (usually) return a different number if you call it a second time. (I think everyone falls into this trap more or less regularly.) – molbdnilo May 17 '19 at 12:15
  • Calling `one.rolled()` twice can produce different values. So the `cout << one.rolled() << endl` may output a different value than is then tested in `if (one.rolled() == 6)`. Store the result of `one.rolled()` in a variable, then print and test the value of that variable. – Peter May 17 '19 at 12:16
  • 1
    `prize = grandtot - (grandtot * .15);` is equivalent to `prize = grandtot * .85;` – Thomas Sablik May 17 '19 at 12:17
  • 2
    `srand(time(static_cast(0)));` You should call this 1 time at the beginning of main and avoid putting it in a loop. Remember that the resolution of the clock is 1 second. And also if the seed is the same you get the same random sequence. Meaning if this loop executes fast enough you will get the same roll multiple times in a row. – drescherjm May 17 '19 at 12:18
  • 1
    class roll is completely unnecessary. It could have been a simple function. – UmNyobe May 17 '19 at 12:20
  • 3
    Please don't use `rand()`. There's whole c++11 new library `` that does RNG correctly. – Quimby May 17 '19 at 12:26
  • @ThomasSablik - not necessarily. Neither 0.15 not 0.85 can be exactly represented using floating point, so subtracting either from one does not (necessarily) give exactly the other. Floating point is like that. – Peter May 17 '19 at 12:28
  • *`~roll() {}`* – Why do you write that? – Swordfish May 17 '19 at 12:30
  • *`roll(int high = 6) { this->high = high; }`* – Use the initialization list: `roll(int high = 6) : high{ high } {}` – Swordfish May 17 '19 at 12:32
  • @UmNyobe it would if it was refactored to have `roll()` and `getRolled()` then the fact that `rolled()` re-rolls the dice wouldn't be quite so misleading. – UKMonkey May 17 '19 at 14:31

2 Answers2

6

Basically, look at @PaulEvans answer for your question. I want to put some focus on your rolled function:

int rolled(int amt = 1)
{
    int done = 0;

    for (size_t x = 0; x < amt; x++)
    {
        done += rand() % high + 1; // <= This line
    }
    return done;
}

Pay attention that you are using rand function to get random values. It's true that you can get random values by using this function, but I would recommend to use C++11 way - with better distribution (don't forget #include ):

int rolled(int amt = 1)
{
    int done = 0;
    std::random_device dev;
    std::mt19937 rng(dev());
    std::uniform_int_distribution<std::mt19937::result_type> dist6(1,6); // distribution in range [1, 6]

    for (size_t x = 0; x < amt; x++)
    {
        done += dist6(rng); // <= This line
    }
    return done;
}

For more details see: https://stackoverflow.com/a/13445752/8038186

Coral Kashri
  • 3,436
  • 2
  • 10
  • 22
5

You're not storing your roll, you want this instead:

const int current_roll = one.rolled();
cout << current_roll << endl;
if (current_roll == 6)
...
Paul Evans
  • 27,315
  • 3
  • 37
  • 54