Random number generator

Hey everyone I just started doing this yesterday, wish I did a long time ago but I never knew what code I wanted or what to use.

Anyway I came across the "Random number generator"
here: http://www.cplusplus.com/articles/EywTURfi/

and managed to make a 3 player dice thing for MTG...

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
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <iostream>

using namespace std;

/* function main begins program execution */
int main(void) {
    cout<<"[y]es, or [n]o?\n";
    cout<<"\n";
    cout<<"Player 1 Roll your Dice? \n";
    cout<<": ";
    string dice;
    cin>> dice;
    if (dice == "y")
    {
    	int i; /* counter */

	srand(time(NULL)); /* seed random number generator */
	/* loop 10 times */
	for (i = 1; i <= 1; i++) {
        		/* pick a random number from 1 to 6 and output it */
		printf("%10d", 1 + (rand() % 20));
    		}
    		cout<<"\n";
    		cout<<"\nPlayer 2 Roll your Dice? \n";
    		cout<<": ";
    		cin>> dice;
    		if (dice == "y")
{
    int i;
    srand(time(NULL));
    for (i = 1; i <= 1; i++) {
        printf("%10d", 1 + (rand() % 20));
    }
    cout<<"\n";
    cout<<"\nPlayer 3 Roll your Dice? \n";
    cout<<": ";
    cin>> dice;
    if (dice == "y")
    {
    int i;
    srand(time(NULL));
    for (i = 1; i <= 1; i++) {
        printf("%10d", 1 + (rand() % 20));
        }
        {
            cout<<"\n";
            cout<<"\nExit [y]es or [n]o? ";
            string exit;
            cin>> exit;
            if (exit == "y")

            return 0;
        }
    }
}
	} /* end for */
    }


feel free to pick it apart, its a tad messy here n their but it wouldn't let me delete allot of it in "codeblocks"

thought i just share that with you guys :)
Last edited on
closed account (E0p9LyTq)
Seeding the C random generator multiple times is a bit of over-kill IMO. Seeding with the current system time, as you are doing, will give you a different random number sequence each time you run your program.
I'm glad you discovered something cool!
But now I'm going to rant.


That article is fundamentally wrong on a number of salient points.

Two things in particular bother me.

Fouad promulgates the use of remainder (%) to "scale" the number returned from rand() (even though modulo/remainder has nothing to do with scaling). And yes, I know it is how people are regularly taught to handle numbers from rand(), but it is incorrect. It introduces unacceptable bias. (See my link below for more.)

But the most egregious problem is that he goes to the effort of creating a histogram of the RNG to probe the distribution, which he then (mis)uses to state the exact opposite of the result:

Fouad wrote:
To show that these numbers occur approximately with equal likelihood, let’s simulate 6000 rolls of a die with the program above so we should say that each number from 1 to 6 should appear approximatly 1000 times.

--snip code--  

Face    Frequency
1          980
2          993
3         1030
4         1009
5         1002
6          986

So we see that each face was chosen nearly 1000 times.
 sic, bold and italic emphases added


What!? No! We see that faces 3, 4, and 5 were significantly more likely to be chosen than 1, 2, and 6. That's what you call a loaded die, and people have literally been shot for playing with one.

(If the distribution were actually equal, you'd see a table of 1000s, plus or minus 1 for rand()'s crudeness. I think Fouad realized that the results weren't as neat as he would have liked, so he used the word "approximately" to make it feel more acceptable, without actually understanding the math he was stomping all over.)

Don't get me wrong. I'm not beating up on Fouad, but he has presented an article with bad misinformation, and there's nothing I can do to flag it as such. Meaning, well-intentioned visitors to cplusplus.com are going to find a nice 4/5 rated article that teaches them bad stuff.


If you really want to learn more about playing with rand(), read the FAQ:
http://www.cplusplus.com/faq/beginners/random-numbers/

(Part two of the FAQ, how-to get random numbers with C++, TRNGs and CSPRNGs, is yet to be written. But what is there is enough to get started with the important principles you must understand about PRNGs.)

Hope this helps.
lol guys like this is my second day don't expect me to understand you :P

all i did was copy that bit change the (rand() % 20)) to 20 and add the cout

its only the second thing I've made, sorry if the article is wrong, go tell him lol...
he did change it so maybe he had it the way you said before??

yea 3 in that definitely stands out i didn't even think about it...

I certainly wouldn't use it in a tourni purely for private use, I have apps for that and real dice lol...

I will take a look thanx...

yea I know about the random each time thats why i chose that bit and i spammed it so i didn't have to exit each roll, i'm guessing i can loop it somehow but yea I'm noob as lol so I'm just having a mess around right now, I know theirs already apps 4 this n stuff but I thought it would be cool to make a lil one like this...

thought someone might find it useful but as you say Duoas its not "right" but at-least it functions thats a + for me lol

Personally I didn't think I would even get that far lol....

I don't mind being told whats wrong gotta learn somehow ay...
Last edited on
Don't feel bad about being a newbie. You've done well. (Very well, actually.)

You don't have to understand everything at first. The problem with stuff that looks really simple is usually that it is wrong for very not-simple reasons.

Read through the FAQ link I gave you. If all you get out of it is some code, then that's enough to get you started random numbering the right way.

1) Seed the PRNG at the beginning of main
2) Write functions (copy and paste them from the FAQ) to get random numbers
3) Use them handily: int die_roll = random_int_in_range( 1, 6 );

:O)
yea Etal weirdly enough is whats given me a bit of a head start in this, why I decided to use C++ it just looked really familiar to me, I'm old so yea c and html are more my style than java I think...

Thanx for the compliment I definitely don't expect to get expect to be an expert any time soon, seem's to me it would take a year just to read the .h files lol which i just found finally!! lol

DUH!! >.< or should i say c:\dir lol

Last edited on
Duoas now I'm no statistician, and I completely agree with you that the % does not make for uniform distribution, but how do you define "significantly more likely"?

Yeah, the 3, 4, and 5 happen to make it to 4 digits while the others were all 3, but to me it seems only the 3 is the outlier in that set of data. 1002 is closer to 993 than 1030 is to 1009. Plus that was really only one "trial" over all, the next 6000 rolls could show a randomly-generated bias for 2.

But going beyond that...
When I use uniform_int_distribution 6000x times, I got
1
2
3
4
5
6
982
949
991
1068
1005
1005

as the result. This "looks" even worse than the first example!

The whole point of what I'm trying to say may be useless, I just disagree with you waving off rand()%N saying that it's significantly more likely based on one trial.

EDIT: But you do explain it correctly in the section in http://www.cplusplus.com/faq/beginners/random-numbers/ so that's good enough for me.
Last edited on
closed account (E0p9LyTq)
@Duoas, does the C++ <random> library provide more uniform distribution?
Yes, see uniform_int_distribution or uniform_real_distribution
Here's an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <random>
#include <ctime>

std::default_random_engine engine(time(nullptr));
std::uniform_int_distribution<int>     dice(1, 6); // range [1, 6] (inclusive both ends)

int main()
{
    int rolls[6] = {0, 0, 0, 0, 0, 0};
    for (int i = 0; i < 6000; i++)
    {
        // dice acts as a "function object", you envoke the () operator with the random number generator as the input
        int rand_roll = dice(engine); // rand_roll will be a number in range[1, 6]
        rolls[rand_roll - 1]++;
    }
    for (int i = 0; i < 6; i++)
    {
        std::cout << rolls[i] << std::endl;
    }
}
Last edited on
Interesting my coding starts a debate? :P

what if you took the result then generated a new roll based on that result?
before rolling??

string num;
cin>> num;
if (num == "1") through 20 (for mine)

back to the RNG? with different setting in each?

hope you can understand my noob statements lol...

excuse me while i bookmark my own thread... :D
Last edited on
> waving off rand()%N

The problem with std::rand() is primarily with the pseudo-randomness quality of the generated numbers. Fixing bias issues associated with the modulus operator alone eliminates only a part of the bias that may be present in the numbers returned by std::rand()

There are no guarantees as to the quality of the random sequence produced. In the past, some implementations of rand() have had serious shortcomings in the randomness, distribution and period of the sequence produced (in one well-known example, the low-order bit simply alternated between 1 and 0 between calls).
rand() is not recommended for serious random-number generation needs, like cryptography. It is recommended to use C++11's random number generation facilities to replace rand(). (since C++11) http://en.cppreference.com/w/cpp/numeric/random/rand


These days, the quality of random numbers generated by std::rand() is a lot better than what it used to be. On current mainstream implementations, std::rand()%N (where N is small compared to RAND_MAX) appears to be adequate for trivial use cases. For quick-and-dirty random number generation, it probably is not worthwhile to use std::rand() and then throw away the one big advantage that it has - performance. For anything more serious, consider using one of the generators with non-trivial state in <random>

A quick test:
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
#include <iostream>
#include <cstdlib>
#include <random>
#include <iomanip>

static const int N = 16'000'000 ;
static const int M = 6 ;

template < typename FN >
void test_it( const char* label, FN&& fn )
{
    std::cout << label << ":\n\n" ;
    int freq[M] {} ;
    for( int i = 0 ; i < N ; ++i ) ++freq[ fn() ] ;
    for( int i = 0 ; i < M ; ++i )
        std::cout << i << ". " << freq[tt] << ' ' << double(freq[tt]*100) / N << " %\n" ;
    std::cout << "\n-------------\n\n" ;
}

int main()
{
    const auto seed = std::random_device{}() ;
    std::srand(seed) ;
    std::mt19937 rng(seed) ;

    // warm up
    for( std::size_t i = 0 ; i < rng.state_size ; ++i ) std::rand() ;
    rng.discard( rng.state_size ) ;

    std::uniform_int_distribution<int> distr( 0, M-1 ) ;

    std::cout << std::fixed << std::setprecision(2) ;

    const auto legacy = [] { return std::rand() % M ; } ;
    const auto current = [&] { return distr(rng) ; } ;

    test_it( "std::rand() % M", legacy ) ;
    test_it( "mt19937, uniform int distribution", current ) ;
}

clang++ -std=c++14 -stdlib=libc++ -O3 -Wall -Wextra -pedantic-errors main.cpp && ./a.out
echo -e '\n===========\n' && g++ -std=c++14 -O3 -Wall -Wextra -pedantic-errors main.cpp && ./a.out
std::rand() % M:

0. 2666604 16.67 %
1. 2667296 16.67 %
2. 2667101 16.67 %
3. 2667151 16.67 %
4. 2666763 16.67 %
5. 2665085 16.66 %

-------------

mt19937, uniform int distribution:

0. 2668573 16.68 %
1. 2664064 16.65 %
2. 2664650 16.65 %
3. 2666695 16.67 %
4. 2666966 16.67 %
5. 2669052 16.68 %

-------------


===========

std::rand() % M:

0. 2666946 16.67 %
1. 2666575 16.67 %
2. 2667594 16.67 %
3. 2665663 16.66 %
4. 2665790 16.66 %
5. 2667432 16.67 %

-------------

mt19937, uniform int distribution:

0. 2666833 16.67 %
1. 2667847 16.67 %
2. 2665853 16.66 %
3. 2667520 16.67 %
4. 2666215 16.66 %
5. 2665732 16.66 %

http://coliru.stacked-crooked.com/a/99b07da5ececb034

Microsoft (VS 2013):
std::rand() % M:

0. 2665141 16.66 %
1. 2665955 16.66 %
2. 2668447 16.68 %
3. 2667211 16.67 %
4. 2666436 16.67 %
5. 2666810 16.67 %

-------------
mt19937, uniform int distribution:

0. 2668983 16.68 %
1. 2665482 16.66 %
2. 2665021 16.66 %
3. 2667969 16.67 %
4. 2666569 16.67 %
5. 2665976 16.66 %

http://rextester.com/TNR65744
hey guys I've been trying to figure out how to use wxwidgets...

guess you probably know what I'm gunna say next... lol...

>.<

firstly when I make a project it says neither my debug or release are their and then i get these

windres.exe -I"C:\Program Files (x86)\CodeBlocks\MinGW\include\wx3\include" -I"C:\Program Files (x86)\CodeBlocks\MinGW\include\wx3\lib\gcc_lib\mswu" -J rc -O coff -i C:\Users\User\Desktop\CBGAME~1\Wiggi\wiggi\resource.rc -o obj\Debug\resource.res
gcc: error: Files\: No such file or directory
gcc: error: \(x86\)\CodeBlocks\MinGW\include\wx3\include: No such file or directory
gcc: error: Files\: No such file or directory
gcc: error: \(x86\)\CodeBlocks\MinGW\include\wx3\lib\gcc_lib\mswu: No such file or directory
windres.exe: preprocessing failed.

I've seen something on changing the #defines in build properties I found where to do it but have lost the page and it was from like 2011 and windows xp solution for an older wx...

I made what I think is a pretty cool lil wigi for this and really want to get it working and try your way's of doing the number generation...

... Stepping Away from the console... lol apparently from what i read its a waste of time??

and yea this widgit thing is sweet as...

am i better off using something other than code::blocks for widgets? or are the other 2D/3D options the same kind of thing? should i just use a different one like Dx9???

seems allot of ppl have problems with widgets in code::blocks??

EDIT: tried again with a different build no matter what i do i get that no debug etc...

nvm i found it think i got it now the dialog box to assing folders came up... which I was looking for goz my wigi wiz stopped bringing it up, I tried before realizing i needed to install wx and then it dissapeared so yeah when i actually installed it, it wasnt letting me set folders... just linking files now...

Nope... lol
Last edited on
Topic archived. No new replies allowed.