Dumb Newb
Cerpin Taxt

I started using Allegro (and...coding) a few days ago, and yesterday I was just messing around, and went to write a little snippet to make a pixel buzz around the screen at random.

It seemed real simple then, but I could never get it to work quite right. It's been bugging me since then, and I can't figure it out. What was meant to be a fun little nothing has turned into a headache.

It's not so much that I want this to work, as I want to know what I'm messing up. No matter what I do, it's always biased to a certain direction, and never makes any major turns. I apologize in advance for all the weird, wrong, badly coded pieces of this source, but I'm sure I'm doing something fundamentally wrong when working with the random numbers.

1#include <allegro.h>
2#include <stdlib.h>
3#include <time.h>
4#include <randomc.h>
5#include "mersenne.cpp"
6 
7int rX, rY;
8int re = 0;
9int x = 400;
10int y = 300;
11int chanceX = 3;
12int chanceY = 3;
13 
14int main(int argc, char *argv)
15{
16 allegro_init();
17 install_keyboard();
18 set_gfx_mode( GFX_AUTODETECT, 800, 600, 0, 0 );
19 
20 BITMAP *buffer = create_bitmap( 800, 600 );
21 
22 while( !key[KEY_ESC] )
23 {
24 TRandomMersenne GrX(re);
25 TRandomMersenne GrY(re/2);
26 
27 rX = GrX.IRandom(1,chanceX);
28 rY = GrY.IRandom(1,chanceY);
29 
30 if( rX > chanceX/2 ) ++x;
31 else if( rX < chanceX ) --x;
32 if( rY > chanceY/2 ) ++y;
33 else if( rY < chanceY ) --y;
34 
35 if( x < 800 && x > 0 && y < 600 && y > 0){
36 putpixel( screen, x, y, makecol( 255, 255, 255 ) );}
37 
38 rest(10);
39 
40 if( rY != 1 ) if( rX == 1 ) chanceX = chanceX + 10;
41 if( rX != 1 ) if( rY == 1 ) chanceY = chanceY + 10;
42 if( rY == 1 ) if( rX != 1 ) chanceX = chanceX - 10;
43 if( rX == 1 ) if( rY != 1 ) chanceY = chanceY - 10;
44 
45 ++re;
46 }
47 return(0);
48}
49END_OF_MAIN();

Oh, and it'd be awesome if someone could post the source of something like a pixel moving around the screen, making more...graceful (but still random) turns. It's not exactly what I wanna do with this, but I've been wondering about the best way to do that.

LennyLen

I'm not familiar with the functions you're using to generate random numbers, but I noticed this:

Quote:

if( rY != 1 ) if( rX == 1 ) chanceX = chanceX + 10;
if( rX != 1 ) if( rY == 1 ) chanceY = chanceY + 10;
if( rY == 1 ) if( rX != 1 ) chanceX = chanceX - 10;
if( rX == 1 ) if( rY != 1 ) chanceY = chanceY - 10;

This is identical to:

if(( rY != 1 ) && ( rX == 1 )) chanceX = chanceX + 10;
if(( rX != 1 ) && ( rY == 1 )) chanceY = chanceY + 10;
if(( rY == 1 ) && ( rX != 1 )) chanceX = chanceX - 10;
if(( rX == 1 ) && ( rY != 1 )) chanceY = chanceY - 10;

The first and fourth conditions are identical, as are the second and third, so this is the same as:

if(( rY != 1 ) && ( rX == 1 )) {
    chanceX += 10;
    chanceY -= 10;
}
if(( rX != 1 ) && ( rY == 1 )) {
    chanceY += 10;
    chanceX -= 10;
}

Which is a lot more readable.

Cerpin Taxt

Thank you.

I know that the number generator and all that are just fine, and the problem is with the way I'm handling the output.

Audric

You are restarting a new number generator every 10ms, seeding it with 1, then 2, then 3, etc. -> Every time you run the game, it will give the same series of results.

If that's not what you want, start the RNG once at the beginning of your program, seeding it with the system time.
Seed the second RNG with a number taken from the first.

edit:
chanceX and chanceY start at 3, then you randomly apply +1 or -1 or +10 or -10, multiple times.
When they become negative, you'll have a hard time getting random numbers >= 1 && <= -7

I think you should printf() the series of numbers you get, to check where the results are going.

Cerpin Taxt

That was the first way I tried it, and for some reason, it would change random values veeeery slowly. (maybe three times a second) The values it's generating are random enough for me (I tested them with scattering some random pixels before setting up the rest of the stuff).

BAF

Your avatar looks strangely familiar.

Anyway, try adding a random number between -x and x to the x and y values. Right now, it looks like you are just either moving by 10 1 or 0, which isn't very random.

Cerpin Taxt

What I'm working on fixing right now is the direction of movment. I want the coordinates to be changed by 1 (or zero) because what I'm trying to randomize is the direction of movement, not the length or distance of the movement.

CosmicR

one way to do it is like this:

1int x = 400;
2int y = 300;
3int dx = 1; // horizontal direction
4int dy = 0; // vertical direction
5 
6int freq = 10;
7 
8int main(int argc, char *argv)
9{
10 allegro_init();
11 install_keyboard();
12 set_gfx_mode( GFX_AUTODETECT, 800, 600, 0, 0 );
13 
14 while( !key[KEY_ESC] )
15 {
16 if(rand()%freq==5) // probably a better way to do this part
17 {
18 switch(rand()%4) // choose a random direction
19 {
20 case 0:
21 dx = 1; dy = 0; break; // right
22 case 1:
23 dx = 0; dy = 1; break; // down
24 case 2:
25 dx = -1; dy =0; break; // left
26 case 3:
27 dx = 0; dy = -1; break; // up
28 default: return;
29 }
30 }
31 x+=dx;
32 y+=dy;
33 clear(screen); // needs double buffering
34 putpixel( screen, x, y, makecol( 255, 255, 255 ) );
35 rest(10);
36 }
37 return(0);
38}
39END_OF_MAIN();

Cerpin Taxt

Thank you very much. That's pretty much what I had in mind.

That being said, for some reason, the movement from my original program looked more...organic(?), I think. I was looking more for this type of movement than the very precise, very square movements. I tried to find a way to influence the next movement by the previous one, so that there would be as little sharp, awkward movements as possible (doubt it worked). If anyone could help me out with this, it would be greatly appreciated.

[EDIT]

I modified it a bit and and got pretty much what I wanted. Thank you very much!

1#include <allegro.h>
2#include <stdlib.h>
3#include <time.h>
4 
5int x = 400;
6int y = 300;
7int dx = 1; // horizontal direction
8int dy = 0; // vertical direction
9 
10int freq = 10;
11 
12int main(int argc, char *argv)
13{
14 allegro_init();
15 install_keyboard();
16 set_gfx_mode( GFX_AUTODETECT, 800, 600, 0, 0 );
17 
18 while( !key[KEY_ESC] )
19 {
20 if(rand()%freq < freq) // just tested it like this (easier than removing all of the loop)
21 {
22 switch(rand()%7) // choose a random direction
23 {
24 case 0:
25 dx = 1; dy = 0; break; // right
26 case 1:
27 dx = 0; dy = 1; break; // down
28 case 2:
29 dx = -1; dy = 0; break; // left
30 case 3:
31 dx = 0; dy = -1; break; // up
32 case 4:
33 dx = 1; dy = 1; break;
34 case 5:
35 dx = -1; dy = 1; break;
36 case 6:
37 dx = 1; dy = -1; break;
38 default: return(0);
39 }
40 }
41 x+=dx;
42 y+=dy;
43// clear(screen); // needs double buffering
44 putpixel( screen, x, y, makecol( 255, 255, 255 ) );
45 rest(10);
46 }
47 return(0);
48}
49END_OF_MAIN();

[/EDIT]

Audric

Then use floats for coordinates, for dx and for dy.(fixed are fine, but usually not popular)
And instead of replacing dx and dy, add or substract a small number to it.

     case 3:
       dx += 0.0; dy += -0.5; break; // up
      case 4:
       dx += 0.35; dy += 0.35; break;

Better put some limits to stop it from becoming too fast:

if (dx > 2.0)
   dx = 2.0;
else if (dx < -2.0)
   dx = -2.0;

Onewing

Just to put in my two cents (and didn't read the whole thread), from what I can tell the above methods are for just random movement. Rarely ever is this sort of movement implemented on some kind of object. Take for example if you applied the above on a NPC in like an RPG type game, the character would appear to be having a ceasure (sp?). A more practical method is to determine a "step" value when you randomly decide the direction. For each movement, you decrease the "step" value. However, you do not allow a new direction until the "step" is less than 0. Now, it appears the object is moving towards a path, when in fact, it is still just as random.

Once again, my two cents.

Quote:

Your avatar looks strangely familiar.

It's almost identical to Kibizor's (sp?)!

LennyLen
Quote:

It's almost identical to Kibizor's (sp?)!


Indeed...

Kibiz0r's: 6203.png

Cerpin Taxt's: 8304.gif

Johan Halmén

They probably can keep their avatars, since they are crawling at the same direction and never will collide and wipe out each other.

BAF

What is that avatar inspired by?

Kibiz0r, is it you?

Cerpin Taxt

I hope I'm not divulging some massive secret here, but it's a 'glider' from Conway's Game of Life.

Jakub Wasilewski

It's also considered the Hacker Emblem by some. Not in the "break into a computer" sense of the word, but rather the "very skilled with computers" sense.

Thread #589958. Printed from Allegro.cc