2

I'm trying to make a death predictor that has a random chance for your character to die as your progress. I'm going to make it have multiple chances to die as well as higher chances the older you grow. How do I fix this basic rand function, to make it so int RandomFactor has a 1-20 number and activates randomly to kill you (sorry if this sounds sadistic)?

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main() {
    srand(time(NULL));
    int RandomFactor;
    RandomFactor = rand();
    20 % 1;

    for (double count = 0; count < 20; count++) {
        if (count < 20) {
            Sleep(360);
            cout << "\n\t\t\tIt's your birthday! You turned: " << count;
        } 
        else
            if (RandomFactor == 1) {
                cout << "\n\n\n\t\t\tBANG! You're dead!";
            }
    }

    cout << "\n\n\n\t\t\t  ";

    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chantola
  • 540
  • 1
  • 5
  • 18
  • 1
    Instead of `RandomFactor = rand(); 20 % 1;` try `RandomFactor = rand() % 20;`. – Galik Sep 11 '14 at 20:33
  • 3 IntelliSense: expected a ';' c:\Users\Parent\Desktop\DeathPredictionv1\DeathPredictionv1\DeathPredictionv1.cpp 18 24 DeathPredictionv1 That's the error message I get If I do that. :( – Chantola Sep 11 '14 at 20:36
  • Intellisense may be intelligent but it is not psychic. It can't predict when you want to make a calculation. – Galik Sep 11 '14 at 20:49

4 Answers4

9

You can use rand % 20 but it won't be truly uniform, it will contain bias. Your better option in C++ is to use std::uniform_int_distribution<> this way

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;
    std::mt19937 gen( rd());
    std::uniform_int_distribution<> dis( 1, 20);

    for ( int n=0; n<10; ++n)
        std::cout << dis(gen) << ' ';
    std::cout << '\n';
}

You can read this to learn more about the bias introduced by rand() % x.

Community
  • 1
  • 1
4pie0
  • 29,204
  • 9
  • 82
  • 118
  • 1
    The bias at this scale is acceptable for pretty much everything except statistics and encryption: low numbers are only 0.0061012812% more likely than high. – Mooing Duck Sep 11 '14 at 20:38
  • I am not sure about your result and we are talking about general case – 4pie0 Sep 11 '14 at 20:42
  • @MooingDuck: If the language already has support for much better randomness why settle for an inferior pattern? Also note how this example seeds with a value that can potentially provide more randomness than `time()` (which could be the same inside precision for different threads/cluster nodes/...). – Benjamin Bannier Sep 11 '14 at 20:42
  • 2
    @BenjaminBannier: Because I can never recall all the bits for this generation, but can always remember `rand()` :/ – Mooing Duck Sep 11 '14 at 20:44
  • @0d0a: You mentioned `rand()%20`, plus an alternative, so I gave you an upvote. `RAND_MAX` is `32768` or higher, so worst case, 0-7 are picked 1639 times, and 8-19 are picked 1638 times (8*1639+8*1638=32768). Then 1639/1638-1 shows that low numbers are picked 0.061050061% more than higher numbers. – Mooing Duck Sep 11 '14 at 20:52
  • I consider this as an error to use rand%20 when you have correct behavior available to use as a std::uniform_int_distribution, it doesn't matter that bias will be 1%, 5% or 0.01%. Apart from this, how did you calculated this (is this in accordance with [this](http://stackoverflow.com/a/24069874/1141471)?) – 4pie0 Sep 12 '14 at 10:47
3

C++ allows you to discard values at your will, so when you do

20 % 1;

It doesn't complain as it calculates it and simply tosses the value.

Perhaps what you meant was in fact:

RandomFactor = rand() % 20;

However, that will result in a number in the range [0, 19], so you probably wanted to add 1:

RandomFactor = (rand() % 20) + 1

So now both ends of the range will be increased by 1, resulting in [1, 20] inclusive.


Furthermore, the if statement

if(count < 20)

will always be true while you are looping (that is the loop condition after all), so the else if will never be run.

scohe001
  • 15,110
  • 2
  • 31
  • 51
  • I would also say that the original implementation doesn't seem to accomplish the goal because the call to rand() is outside of the loop, so it will have the same value for each loop iteration. Either everybody is dead or nobody is – rdowell Sep 11 '14 at 20:42
  • @rdowell Perhaps `RandomFactor` is calculating whether or not there will be a zombie apocalypse, in which case that would be correct. Who's to say? – scohe001 Sep 11 '14 at 20:43
0

Try using drand(), it will return a uniform number between 0 and 1, which you can then scale. Which you can initialize with srand48(seed). For example, if you want a 20% chance to trigger you could do:

 if( drand() <= 0.05f ) // (5% chance)
     // do something

Or alternatively

int randomNumber = ceil( drand()*20 ); 
// creates a uniform distribution between 1 and 20, inclusive
vasimr22
  • 1
  • 1
-3

There shouldn't be a semi-colon after rand(). Try RandomFactor = rand() 20 % 1;

Will Pace
  • 56
  • 5