# Need Help! Random in MFC

• 09-17-2010
stephencalderon
Need Help! Random in MFC
Greetings!
I'm a beginner, still in school. I'm doing a small project in MFC. It's a basic animation of a ball bouncing off the four wall in a square. I don't exactly understand what this does randomly : srand((unsigned)time (NULL)). Also how would I use this to make the ball bounce randomly on the walls? Sorry if this is simple. Right now it bounce SE to SW to NW to NE. Once it hits the corners the ball then bounces across from corner to corner stuck that way.
Thanks!
• 09-17-2010
smokeyangel
srand((unsigned)time (NULL)) seeds the random number generator. You only need to call it once. Then you call rand() to get random numbers.

Code:

```int rnd; rnd = rand(); // random number between 0 and RAND_MAX```
You can pass any unsigned integer to srand. But if you pass a constant, e.g. srand(100) the "random" values from rand will be the same every time you run the program. That's not what you want, but can be useful for debugging.

For a ball randomly bouncing off a wall....
Sorry, I don't know enough about MFC!
I guess the ball's direction is determined by incrementing/decrementing coordinates? Then you could use rand() to determine the increment -- a higher increment in one axis will make the ball advance in a different direction.
You'd have to use the modulo operator % on the value return from rand, then probably divide it to get a sensible value. Then probably do some more bounds checking.

Might be completely off the mark with that - just a guess.
• 09-17-2010
dwks
The standard C library (which C++ inherited) allows you to generate pseudo-random numbers using the rand() function. The trouble is that each time you call rand() a sequence of times, you get the same sequence of numbers. So there's also a function called srand() that allows you to "seed" the random number generator with some integer. Each integer gives you a different sequence of random numbers.

In order to get a different seed, you can use time() to return the number of seconds since January 1st, 1979 (the so-called Unix epoch). This is a reasonably good thing to use as a seed since the time changes every second. But you'll notice that if you run a program using this seeding method twice within one second, it will give you the same sequence of numbers. :)

Note that rand() returns a number in the range [0, RAND_MAX] where RAND_MAX is at least 2^15 and more often 2^31. To get a number in the range [0, N) you can use "rand() % N", but see this: Eternally Confuzzled - Using rand()

To make your ball bounce randomly, I'd do something like this. Calculate the incident vector (the direction the ball is moving in), find out which wall it's bouncing off of, and use that to calculate the reflected vector (the direction the ball will soon be moving in). You can use a random number to rotate the reflected vector by say +/- 10 degrees and you may see some interesting results.

 A bit more math: suppose your ball is traveling xs units horizontally and ys units vertically every frame. A vector pointing in the direction of the movement will just be (xs, ys). If you hit the left-hand side of the screen then you'll want to change the movement to (-xs, ys), in other words, invert the X axis. To add a little randomness you could just take this vector and rotate it slightly +/- 10 degrees. If you recall some linear algebra you'll know that the rotation formula in 2D is quite simple:
Code:

```newx = x*cos(angle) - y*sin(angle); newy = x*sin(angle) + y*cos(angle);```
(Yeah, I had to look it up too: http://en.wikipedia.org/wiki/Rotatio...Matrix_algebra)

The only tripping point here is that angle must be in radians. So anyway, suppose you want to rotate a vector by +/- 10 degrees; you could use something like this.
Code:

```#define PI 3.14159265358979324 void rotateRandomly(double x, double y, double &newx, double &newy) {     int angle_degrees = (rand() % 20) - 10;  // random angle in degrees     double angle = angle_degrees * PI / 180.0;    // in radians     newx = x*cos(angle) - y*sin(angle);     newy = x*sin(angle) + y*cos(angle); }```
Pass your (-xs, ys) or whatever the new vector is into this function and you'll get a slightly randomized one back . . . . [/edit]
• 09-17-2010
BMJ
So what are you more curious about: how to draw the ball, how to make it bounce randomly off of walls, or how to use MFC in general?
• 09-17-2010
stephencalderon
Thanks for you responses.
Smokeyangel: increasing/decreasing the x,y coordinates cause the ball to move faster. Raising just one made the ball freak out. So wouldn't messing with them in that way screw things up?

BMJ: I basically have a pic of a pool ball that I have bounce off the walls in order from SE, SW, NW, NE, basically tracing a diamond in the box. My main focus is to get the ball bouncing randomly, also once the ball makes its rounds twice or so its gets stuck bouncing from the top left corner to the bottom right corner.
• 09-18-2010
BMJ
Since you're dealing with a ball bouncing inside of a square you don't need to worry about complex calculations involving angles of incidence and reflection, it's very straightforward in this situation.

On each "draw frame" the ball (its center) is being moved in 2 directions: the X direction and Y direction.
When you've detected that the ball has hit a vertical wall, simply reverse the magnitude of X (e.g. 5 would become -5)
When you've detected that the ball has hit a horizontal wall, simply reverse the magnitude of Y (e.g. -2 would become 2)

But this isn't very interesting, is it? You end up with a situation like you previously described.

How can you make it more interesting?

First, the starting X and Y values (representing the velocity of the ball) should be set to random values so that the ball doesn't always start moving in the same direction. The values could be random, for example between -10 and 10.

Next, each time the ball hits a wall, rather than merely reversing the magnitude you can disturb the velocities by adding or subtracting some other randomly generated value (a very small one).

This way the ball wont just bounce around in a diamond pattern. :)
• 09-18-2010
CommonTater
Quote:

Originally Posted by stephencalderon
Greetings!
I'm a beginner, still in school. I'm doing a small project in MFC. It's a basic animation of a ball bouncing off the four wall in a square. I don't exactly understand what this does randomly : srand((unsigned)time (NULL)). Also how would I use this to make the ball bounce randomly on the walls? Sorry if this is simple. Right now it bounce SE to SW to NW to NE. Once it hits the corners the ball then bounces across from corner to corner stuck that way.
Thanks!

You could use rand() as a means to vary the angle of rebount, making sure the ball doesn't find some static angle and resolve itself to bouncing continuously off the same points of the square.

srand() is a seeder for the random number generator. It creates a new sequence of pseudo random numbers for the rand() function to use. It's weakness is that if you use the same number every time (as previously explained) you will get the same sequence every time.

time() is the number of seconds since 00:00hrs Jan 1, 1970. Using it as a seed in srand pretty much guarantees you won't get the same sequence twice.
• 09-18-2010
novacain
I would use a timer to do this.

OnInit()
Create a Compatible DC and bitmap for the background.
Load or create the ball bitmap.
Create a timer event (sends a OnTimer() message every time-period ie 1/sec)
call srand(time)

OnTimer()
Calc new ball position
FillRect() on background DC (to erase balls current position)
Draw ball on background DC
Call for a paint msg (OnPaint()) with

InvalidateRect() //generate paint msg
UpdateWindow() //Bypass OS msg queue and send the paint directly to the app

OnPaint()
BitBlt the background DC to the screen using the DC and CRect in the OnPaint() params

OnClose()
Clean up the background DC and ball image.
Kill timer

EDIT: rand() is a just a very big list of numbers.
srand() sets the starting position within the list
rand() gets the next number from the list (and moves the position one forward, so the next call gets the next number, etc).