9

I am making a text-based C++ RPG and I am trying to figure out how to work out the amount of damage that the enemy hits you for. My idea is something like this.

Damage done = randomIntBetween10and20*enemyLevel

This way it doesn't always hit for a set amount each time and allows there to be Critical Strikes (For example, if the hit is above 15 I would class that as a Critical Strike)

I'm new to C++ so I'm not quite sure how I can do this, any help would be greatly appreciated.

Luke Berry
  • 1,927
  • 4
  • 19
  • 32
  • Is your problem the generation of random numbers? Have a look here: http://stackoverflow.com/questions/3786389/write-a-c-function-that-generates-one-random-number-or-a-pair-of-random-numbers/3786809#3786809 – Matteo Italia Dec 10 '10 at 20:51
  • 10
    Is it bad that I first read RPG as Rocket Propelled Grenade? – Billy ONeal Dec 10 '10 at 21:00
  • 7
    @Billy ONeal, it's not bad at all... it's text based. At the very least the combatant will suffer serious ASCII injuries. – Moo-Juice Dec 10 '10 at 21:09
  • Did you really mean TRULY? If so, you have to be EXPERIENCED A LOT with C++. Using microphone noise can be profitable :) – Петър Петров Aug 18 '13 at 14:31
  • Somebody please edit the title of the question. As plenty of people have pointed out this question has nothing to do with a True Random Number Generator (TRNG). – Potaito Mar 13 '15 at 08:28

8 Answers8

27

You should omit the word "truly" from the title, because you probably don't mean it. You probably just want a pseudorandom number. True randomness is virtually impossible to achieve with a personal computer. The following snippet will give you a pseudorandom number in the range 10..19 inclusive:

#include<cstdlib>
#include<ctime>

// ...
srand(time(0));
int r = rand() % (20 - 10) + 10;

If you want to include 20 in the range then this is a range of 11 numbers:

int r = rand() % (21 - 10) + 10
Paul R
  • 208,748
  • 37
  • 389
  • 560
wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
  • At least this one mentions the difference. +1 – Edward Strange Dec 10 '10 at 20:59
  • 3
    Quite a few PCs actually have a random input stream based on thermal noise, which includes true randomness. See http://en.wikipedia.org/wiki/Hardware_random_number_generator – Ben Voigt Dec 10 '10 at 20:59
  • You have to specifically ask for them though. The rand() function is pseudo-random. – Edward Strange Dec 10 '10 at 21:02
  • 4
    don't forget. Only call srand() **once** in an application. – Martin York Dec 10 '10 at 21:14
  • @Ben: for a suitable definition of "true random", of course. ;) – jalf Dec 11 '10 at 00:36
  • @jalf: Thermal noise isn't uncorrelated white gaussian, if that's what you're getting at, but there is some uncorrelated noise mixed in on top of the other stuff. And I would guess that HW RNG is pretty well equipped to separate that out. – Ben Voigt Dec 11 '10 at 00:50
  • @Noah: Yes you do need different code. My comment was directed at wilhelmtell's statement that "True randomness is virtually impossible to achieve with a personal computer", not the code snippet. – Ben Voigt Dec 11 '10 at 00:51
  • 1
    I only have one issue with this snippet: I'm afraid it's biased. If we suppose that `rand()` is unbiaised (to begin with), then `rand() % N` is slightly more likely to yield `0` than to yield `N-1`, unless `N-1` is a divisor of the maximum value that `rand` may generate (or something like that :p). If `N` is small, it's not that noticeable (`1,000,0001` 0 for `1,000,000` 10 for example, would be almost unbiaised), but with N growing the issue is more and more important. I don't know any way to get a uniform distribution in `0..N` in O(1) time though. – Matthieu M. Dec 11 '10 at 11:29
7

A good choice would be std::random, the random number generator that’s built-in to C++.

If you don’t have C++11 support yet, use boost::random. The new std::random is based on boost::random, so it’s basically the same thing. The documentation has several examples, including Generating integers in a range.

One of the options offered is the Mersenne Twister (mt19937), which is a good general-purpose pseudo-random number generator.

Like most of the other suggestions, this is pseudo-random. To get true randomness is more difficult—but you don’t need that for an RPG, right? (For cryptographically-strong random numbers, consider OpenSSL or, on Windows, CryptoAPI.)

Community
  • 1
  • 1
Nate
  • 18,752
  • 8
  • 48
  • 54
  • 1
    Well, I'd not call C++0x the "latest version", given that it is not yet C++. – Billy ONeal Dec 10 '10 at 21:10
  • Meh, it’s close. How about, “upcoming version?” I use `std::random` all the time in MSVC and I know `gcc` 4.5 supports it too. – Nate Dec 10 '10 at 21:19
4

The stdlib random number generator would be an okay place to start:

#include <stdlib.h>
#include <time.h>

srand(time(NULL)); // initialize the RNG
int poll = rand() % 20; // random number between 0 and 19 inclusive

Eventually, you'll want to start using a more random RNG. Game Coding Complete has a pretty decent one to get you started.

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • 8
    Note that `srand` should be called **ONCE** and never again! (Not every time) – Billy ONeal Dec 10 '10 at 20:55
  • @Noah: No RNG is really "truly" random. All are only psuedo-random. For what he is asking, either of those options would be "random enough". – Zac Howland Dec 10 '10 at 20:56
  • Thankyou, this is just what I need. Apparently I can't set an accepted answer for another 6 minutes, so I will wait. – Luke Berry Dec 10 '10 at 20:57
  • @Zac: Not true. See Noah's answer. Most machines *do* have some system specific ways of getting true random (though not quite as good as something like random.org). For example, `/dev/random` on Linux boxes are generated from such./ – Billy ONeal Dec 10 '10 at 20:57
  • @Billy: /dev/random and even random.org are only pseudo-random number generators. If you notice, random.org states that it offers "true" random numbers that are "better" than other psuedo-random number generators. Better random number generator, sure ... truly random, nope. But we have gone off on a huge tangent here. – Zac Howland Dec 10 '10 at 21:02
  • @Zac: I'm sorry, but you are incorrect. Both the sources I mention are truly random. That's why reading from `/dev/random` is insanely slow, because there's not much randomness to be had on a typical PC, while `/dev/urandom` is fast, because it is pseudorandom. – Billy ONeal Dec 10 '10 at 21:09
  • 1
    @Billy: Hate to break it to you, but you are incorrect. There is only 1 known true random number generator "algorithm" (I use the term very loosely there) that we've found so far. Every other software solution is pseudo-random to varying degrees. Just because a pseudo-random number generator is better than another, does not make it truly random: http://en.wikipedia.org/wiki/Random_number_generation#.22True.22_random_numbers_vs._pseudorandom_numbers – Zac Howland Dec 10 '10 at 21:14
  • @Zac: I don't see how that link proves your point. All it says is that a deterministic machine cannot produce true random numbers. Neither `/dev/random` nor random.org are generated via deterministic processes. – Billy ONeal Dec 10 '10 at 21:20
  • 1
    @Zac: The random.org site is not a software solution. – Edward Strange Dec 10 '10 at 21:29
  • 1
    @Billy: True randomness can not be calculated. So unless a standard PC has a way to measure some physical phenomena (to get the required entropy) that I am unaware of then /dev/random must calculate a randm number and as such is a PRNG and thus not truly random. – Martin York Dec 10 '10 at 21:29
  • @Zac: AFAIK `/dev/random` picks up entropy from various "casual" hardware stuff (the entropy pool), e.g. from mouse movements, keypress timings, etc. See http://en.wikipedia.org/wiki//dev/random#Linux, http://en.wikipedia.org/wiki/Entropy_pool#Using_observed_events – Matteo Italia Dec 10 '10 at 21:31
  • @Martin York: Yes, most PC's don't have many sources of entropy, which is why reading any substantial amount of information from `/dev/random` takes forever. Most PCs do have some limited random generation facilities however, for example, via clock drift or thermal noise. – Billy ONeal Dec 10 '10 at 21:32
  • @Billy: random.org and [ERNIE](http://en.wikipedia.org/wiki/ERNIE#ERNIE) use hardware to measure physical phenomena (that apparently are random). You can of course get [appropriate hardware](http://en.wikipedia.org/wiki/ERNIE#ERNIE) to plug into your PC but it has an associated cost that most people are not willing to pay for (do most people truly need true randomness). So yes PC can generate truly random numbers, but most don't as PC manufacturers are not willing to add to the cost of a PC for something that most people don't care about. /dev/random is slow because it is trying to be good. – Martin York Dec 10 '10 at 21:39
  • @Billy: If you want to continue this discussion ask the question on SO is "/dev/random" truly random? " – Martin York Dec 10 '10 at 21:45
  • @Martin: I don't need to. http://en.wikipedia.org/wiki//dev/random#Linux already explains it pretty damn well. – Billy ONeal Dec 10 '10 at 21:56
  • @Billy: Yes because Wikipedia is a good accurate source of information written by the most knowledgeable people in the field! I love Wikipedia as a starting point for research to find other **authoritative** sources, but as a source it is not a good one (even wikipedias' founder makes this exact statement). – Martin York Dec 10 '10 at 22:15
  • @Billy: I read the wikipedia page. Which provided [this link](http://everything2.com/title/%252Fdev%252Frandom) in the reference section. That explains that /dev/random uses random noise from the PC to seed the random number generator. SO which do I believe? – Martin York Dec 10 '10 at 22:20
  • @Martin: If you cannot model it as anything other than random then it is random. – President James K. Polk Dec 10 '10 at 23:02
  • @Martin: Perhaps more appropriate than an ERNIE link for people who might want to add hardware RNG to a PC: http://en.wikipedia.org/wiki/Comparison_of_hardware_random_number_generators And yes, initializing a PRNG with a truly random seed can increase the bitrate without sacrificing (much) randomness. – Ben Voigt Dec 11 '10 at 01:01
  • @GregS: Yes that is what the crypto world believes. Please feel free to ask the question on SO. See if the majority believe that. @Ben: sure I agree with you it is better than rand() that was not point. @Billy as arguing that /dev/random was truly random. Whoops my second link was supposed to be the one you provided. Thanks. – Martin York Dec 11 '10 at 03:37
2

As others said, maybe rand() will be really sufficient for you. What is important is the seed used to initialise the pseudo random number generator ( the call to srand() is the seed)

But beware, True Chaos doesnt mean that you have exactly the same chance to generate any possible random output.

Ten years ago I have played with stochastic sound generation. I needed several sources of chaos.

I just let you know those which I had kept and found useful. of course since they need a seed, they are pseudo chaos.

1/for chaotic float number between -1 and 1: compute the function f(x) = cos(exp(x)). exp() grows so fast, that after really few iteration, what goes out from cos() is chaos.

2/the baker transform: chaotic number between 0 and 1: take a number, multiply it by two, and again, when it is superior to 1, substract something so as it goes back betwen 0 and 1. A much more precise explanation The Baker Transform.

But I think rand() and srand() will satisfy you.

For applying to your range 10-20, of course you stretch/scale the chaotic range (0;1) or (-1;1) by multiplying and offsetting so as the ouput fits your need. ;-)

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
2

The method that uses modulus (%) isn't a good choice because the distribution is off. This is better:

double GetRandom(double Min, double Max)
{
    return ((double(rand()) / double(RAND_MAX)) * (Max - Min)) + Min;    
}

You will need to include algorithm and seed the generator with srand.

Of course, it's only pseudo-random. You won't be able to get truly random results, especially with rand.

Maxpm
  • 24,113
  • 33
  • 111
  • 170
1

The only way to 'generate' a truly random number is through the interaction with some environmental factor that is random. This website provides a service that does that for you: http://www.random.org/

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
0

look this out, it might be helpful:

// random numbers generation in C++ using builtin functions
#include <iostream>

using namespace std;

#include <iomanip>

using std::setw;

#include <cstdlib>   // contains function prototype for rand

int main()
{
// loop 20 times
for ( int counter = 1; counter <= 20; counter++ ) {

    // pick random number from 1 to 6 and output it
    cout << setw( 10 ) << ( 1 + rand() % 6 );

    // if counter divisible by 5, begin new line of output
    if ( counter % 5 == 0 )
        cout << endl;

}

return 0;  // indicates successful termination

} // end main
0

Use srand() to initialise the random number generator:

srand(time(NULL));

http://www.cplusplus.com/reference/clibrary/cstdlib/srand/

Then use the rand() function to generate a sequence of random numbers.

http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

ryyker
  • 22,849
  • 3
  • 43
  • 87
John
  • 15,990
  • 10
  • 70
  • 110