srand(); C++ question

Pages: 12
Hi, i am using "srand(1);" and "int random = rand() % 5;" in my code.

When i change the value in "srand(1)" to different numbers i get different results. However, the results are exactly the same for the random generator when every run. I have tried using "srand(time(NULL))" but that keeps changing my results after I have called them.

For example, a square has its colour generated by the rand but once the square exists and is displayed, the colour keeps changing when i use "srand(time(NULL))" but if i use srand(1); my box stays the same colour once generated but always generates the same result each run.

Anyone know if there is something i'm missing, im brand new to randomisers in C++ and i'm finding this a mite confusing
If you pass the same number to srand you will get the same sequence of random numbers from rand. If you call srand with the same number before each call to rand the sequence is reset so that you get the same number each time.

Only call srand once, at the beginning of the program.
Last edited on
The behaviour described sounds normal. srand() supplies a seed to initialise the random number generator. Normally you would do this just once at the start of the program.

During testing and debugging, it can be useful to generate the same sequence on each run, so you might supply a specific seed. But generally, the requirement is that each run should be different, so time(NULL) is used.

Having said that, did you just need an explanation, or is there a problem that needs to be fixed (if so, I missed it, sorry)?
that's the thing, i've seen that said before and my problem is that i want to generate like 20 random numbers each run. So i put" int random = rand() % 5" in a for loop and srand(1); or srand(time(NULL)); outside the loop at start of program, expecting it to generate a new number each time. It does but with the stated problem.

What the problem is, is that I have srand(1); at the start of my code already but i keep getting the same results each time i separately start the program which is not random like i want.

is there a version of srand(); that will be different each run but not keep changing like "srand(time(NULL))"?

thanks for reply tho

the folliowing is the specific code that controls colour within the for loop:

int random = rand() % 5;
cout << random << endl;

if (random < 2){
squareColour = 0;
}else{
squareColour = 1;
}

glColor3f(squareColour, squareColour, squareColour);



with time(NULL) my colour keeps changing even after the squares have been displayed which i dont want. I want a random result each run, that then stays the same and doesnt change until the program is re-run.
Last edited on
with time(NULL) my colour keeps changing even after the squares have been displayed which i dont want.

The colour will of course change if you repeatedly call the code posted above.

The trivial answer is to call the code to set the colour just once. Then there's no way it can change.
but won't that make all my spaces the exact same colour instead of alternating black and white?

like if all the spaces have been generated the for loop should have done its job and that part of the program should stop, i dont see why the colours keep changing.

but it keeps generating and changing colours. Even if i take the call to rand outside the for loop, i get all my spaces the same colour and they also keep changing every second. So im basically getting an all black board changing to an all white board every so often and back again.


also, im noticing a lot of mentions about only having srand() called in main. but im using rand outside main. is this the problem?

thanks again for your support, I've been trying to fix this problem for about 5 hrs total now.
Last edited on
Set them all to a random color once each.
There's not enough information here to give a useful answer, the way the rest of the program logic fits together is crucial.

If possible, post the complete code, or if its too large, try to edit it down to remove unrelated code before posting.
ok ill show you the specific part of my code that creates the grid and a picture of what im outputting. I didn't want to do this at first because i tried it yesterday and got no responses :p

void OGWindow::drawGrid(GLvoid){

	int squareColour = 1;
	int size = 7; 
	srand(time(NULL));

	
	
	for (int xValue = 0; xValue < size; xValue++)
	{
		for (int yValue = 0; yValue < size; yValue++)
		{
			if (xValue == 0  && yValue == 0)
			{
					glColor3f(1, 0, 0);
                                        //code removed, draws square

					glColor3f(0, 0, 0);
					//start square outline

			} else if (xValue == size - 2  && yValue == size - 2){

					glColor3f(0, 0, 1);
					//an end square
					glColor3f(0, 0, 0);
					//end square outline
	
			} else {
				
					glColor3f(0, 0, 0);
					//square outline

					int random = rand() % 5;
					//int random = 1 + rand( ) % 5;
					cout << random << endl;

					if (random < 2){
								squareColour = 0;
					}else{
								squareColour = 1;
					}


					glColor3f(squareColour, squareColour, squareColour);
					//making a square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();
				
		}

	}
}

}


and picture
http://i50.photobucket.com/albums/f342/liboempire/Capture.png
but basically, everything but the red and blue space, keep changing randomly with each second.
Last edited on
Well, assuming this function is called multiple times, yes the colour will change each time.

My first comment is that the srand() call should not be here inside this function at all, it should be in the main function.

However, if you do that, it won't actually solve the problem.

What I think you need is a 2D array (to correspond with the xValue and yValue) in which to store the value of the colour.

Then, you would simply do squareColour = savedColour[xValue][yValue]; instead of using the random number each time.

That still leaves the problem of how to get the colours stored in that array. One way would be to have a separate function which is called just once before drawing anything to the screen, and call rand() in that function, then save the value to the array.

That's just a rough idea, there may be other approaches, but one way or another you need to store the random colour at the start, then use the stored value after that.
Last edited on
that does sound correct but unfortunately I am way to noobish to know how to do that lol.

Thank you very much for your help but i think what ill do is simply have the user at the start, choose a number and this will be used to choose the x in srand(x); and choose the size of the grid thus simulating randomness but with predictable results if you did the exact same thing.
The code you already have is quite advanced, you can't be that much of a beginner :)


Anyway, all you need is something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const int size = 7;
int saveColour[size][size];

void initColour()
{
    int squareColour = 1;

    for (int xValue = 0; xValue < size; xValue++)
    {
        for (int yValue = 0; yValue < size; yValue++)
        {
            if (rand() % 5 < 2)
                squareColour = 0;
            else
                squareColour = 1;

            saveColour[xValue][yValue] = squareColour;
        }
    }
}

At the start of your program, call srand() then initColour()


After that, just use saveColour[xValue][yValue] inside function OGWindow::drawGrid(GLvoid) in place of the existing random number stuff.
Last edited on
ooh, sounds interesting. Ill give that a shot right now and let you know how it goes :D
ok, now where i show my noobishness. When you say use saveColour[xValue][yValue] inside function OGWindow::drawGrid(GLvoid). Where exactly are u thinking? I've removed most of the code that existed down to the following
(i am calling const int size = 7;
int saveColour[size][size];
at the top outside any method):

void initColour()
{
    int squareColour = 1;

    for (int xValue = 0; xValue < size; xValue++)
    {
        for (int yValue = 0; yValue < size; yValue++)
        {
            if (rand() % 5 < 2)
                squareColour = 0;
            else
                squareColour = 1;

            saveColour[xValue][yValue] = squareColour;
        }
    }
}


void OGWindow::drawGrid(GLvoid){

	int size = 7; 
	//srand();

	
	
	for (int xValue = 0; xValue < size; xValue++)
	{
		for (int yValue = 0; yValue < size; yValue++)
		{
			if (xValue == 0  && yValue == 0)
			{
					glColor3f(1, 0, 0);
					//start square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue+0.3, 0.0);
					glVertex3f(xValue-0.3, yValue+0.3, 0.0);
					glEnd();

					glColor3f(0, 0, 0);
					//start square outline
					glBegin(GL_LINE_LOOP);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();

			} else if (xValue == size - 2  && yValue == size - 2){

					glColor3f(0, 0, 1);
					//an end square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue+0.3, 0.0);
					glVertex3f(xValue-0.3, yValue+0.3, 0.0);
					glEnd();

					glColor3f(0, 0, 0);
					//end square outline
					glBegin(GL_LINE_LOOP);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();

			} else {
				
					glColor3f(0, 0, 0);
					//square outline
					glBegin(GL_LINE_LOOP);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();

					//saveColour[xValue][yValue];

					glColor3f(squareColour, squareColour, squareColour);
					//making a square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();
				
		}

	}
}

}


i'm not sure what i actually do with the values.
Last edited on
Change the commented line
 
//saveColour[xValue][yValue]; 

to
 
squareColour = saveColour[xValue][yValue];


That way, each time drawGrid is called you will be using the saved color for drawing the square. drawGrid gets called anytime the screen needs to be repainted. That's why when you were calculating a random square color inside drawGrid your squares kept changing colors.


Please use code tags (the <> formatting button), not the quote tag when posting code.
[code]
code here
[/code]

Last edited on
yeah thats what i thought was required, i had already made the following changes but the problem is that the entire grid becomes one colour again. My code being :

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
void initColour()
{
    int squareColour = 1;

    for (int xValue = 0; xValue < size; xValue++)
    {
        for (int yValue = 0; yValue < size; yValue++)
        {
            if (rand() % 5 < 2)
                squareColour = 0;
            else
                squareColour = 1;

            saveColour[xValue][yValue] = squareColour;
        }
    }
}


void OGWindow::drawGrid(GLvoid){

	int squareColour = 1;
	int size = 7; 
	//srand();

	
	
	for (int xValue = 0; xValue < size; xValue++)
	{
		for (int yValue = 0; yValue < size; yValue++)
		{
			if (xValue == 0  && yValue == 0)
			{
					glColor3f(1, 0, 0);
					//start square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue+0.3, 0.0);
					glVertex3f(xValue-0.3, yValue+0.3, 0.0);
					glEnd();

					glColor3f(0, 0, 0);
					//start square outline
					glBegin(GL_LINE_LOOP);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();

			} else if (xValue == size - 2  && yValue == size - 2){

					glColor3f(0, 0, 1);
					//an end square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue-0.3, 0.0);
					glVertex3f(xValue+0.3, yValue+0.3, 0.0);
					glVertex3f(xValue-0.3, yValue+0.3, 0.0);
					glEnd();

					glColor3f(0, 0, 0);
					//end square outline
					glBegin(GL_LINE_LOOP);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();

			} else {
				
					glColor3f(0, 0, 0);
					//square outline
					glBegin(GL_LINE_LOOP);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();

					 squareColour = saveColour[xValue][yValue];

					glColor3f(squareColour, squareColour, squareColour);
					//making a square
					glBegin(GL_QUADS);
					glVertex3f(xValue-0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue-0.5, 0.0);
					glVertex3f(xValue+0.5, yValue+0.5, 0.0);
					glVertex3f(xValue-0.5, yValue+0.5, 0.0);
					glEnd();
				
		}

	}
}

}


and yeh srry, ill put all code in required format
Last edited on
You're using the [output] tags, you need to be using the [code] tags. Just edit your post and replace "output" with "code"
ah ok, changed, now i see what you meant, i thought u were referring to the bits of code i didn't do anything to
ok actually, how do i appropriately call srand(); and initColour(); at the start of the program?

This is where i think i'm creating my problem as those commands on their own come with a barrage of errors when i put them anywhere that seems logical.
Last edited on
Not sure what environment you're working in, but you must have someplace in main() or your initialization code that only every gets called once.
Pages: 12