Tille - I can see you, read those man pages!   Tille's Site

Random effects

The rand() function is in the standard library, see man 3 rand. The actual documentation explaining how to let this function generate random numbers is in the glibc docs. Usually, the machine's time is taken to be the seed to initialize the random number generator. Therefore, we will have to include time.h. A simple example of the usage:

/* Program name: giverandom.c */
 
# include <stdlib.h>
# include <stdio.h>
# include <time.h>
 
void genrandom() {
  long myrandom = rand();
  long smaller = myrandom/(RAND_MAX/255);
  printf("Generated %ld.\n", smaller);
}
 
int main()
{
  srandom (time (0));
  genrandom();
  genrandom();
  genrandom();
  return(0);
}

The value of the random number is way too high, so we divide by RAND_MAX and multiply with the maximum allowed random value. We take 255 for that, because RGB values for colours are between 0 and 255. Because we're a bit lazy, we will make a function out of this program and use the same random function to determine random X- and Y-offsets.

/* Program name: random1.c */
/* SDL screen test */
                                                                                
# include <SDL.h>
# include <stdio.h> /* Actually best to always include this. */
# include <stdlib.h>
# include <unistd.h>
# include <math.h>
/* For the time function. */
# include <time.h>
                                                                                
/* Begin DrawPixel. */
void DrawPixel(SDL_Surface *screen, int x, int y,
Uint8 R, Uint8 G,
Uint8 B)
{
/* Don't fail on attempts to draw outside the screen. */
if ((x>=640) || (x<0)) return;
if ((y>=480) || (y<0)) return;
                                                                                
    Uint32 color = SDL_MapRGB(screen->format, R, G, B);
                                                                                
    if ( SDL_MUSTLOCK(screen) ) {
        if ( SDL_LockSurface(screen) < 0 ) {
            return;
        }
    }
                                                                                
    switch (screen->format->BytesPerPixel) {
        case 1: { /* Assuming 8-bpp */
            Uint8 *bufp;
                                                                                
            bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
            *bufp = color;
        }
        break;
                                                                                
        case 2: { /* Probably 15-bpp or 16-bpp */
            Uint16 *bufp;
                                                                                
            bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
            *bufp = color;
        }
        break;
                                                                                
        case 3: { /* Slow 24-bpp mode, usually not used */
            Uint8 *bufp;
                                                                                
            bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
            if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
                bufp[0] = color;
                bufp[1] = color >> 8;
                bufp[2] = color >> 16;
            } else {
                bufp[2] = color;
                bufp[1] = color >> 8;
                bufp[0] = color >> 16;
            }
        }
        break;
                                                                                
        case 4: { /* Probably 32-bpp */
            Uint32 *bufp;
                                                                                
            bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
            *bufp = color;
        }
        break;
    }
    if ( SDL_MUSTLOCK(screen) ) {
        SDL_UnlockSurface(screen);
    }
    SDL_UpdateRect(screen, x, y, 1, 1);
                                                                                
}
/* End DrawPixel. */
                                                                                
/* Begin DrawCircle. */
void DrawCircle(SDL_Surface *screen, int rrr, int ggg, int bbb, int radius, int
offsetx, int offsety) {
  float i;
  for (i=0; i<2*M_PI; i+=0.01) {
    int x = offsetx + radius*cos(i);
    int y = offsety + radius*sin(i);
    DrawPixel(screen, x, y, rrr, ggg, bbb );
    }
}
                                                                                
/* End DrawCircle. */
                                                                                
/* Begin randomcolor */
int randomcolor() {
  int myrandom = rand()/(RAND_MAX/255);
  return(myrandom);
}
/* End randomcolor */
                                                                                
int main()
{
  SDL_Surface *screen;
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
  }
  atexit(SDL_Quit);
                                                                                
  screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
    if ( screen == NULL ) {
        fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
        exit(1);
    }
                                                                                
  printf("Set window of 640x480 at %d bits per pixel mode\n",
        screen-format->BitsPerPixel);
                                                                                
/* Set random seed. */
  srandom(time (0));
                                                                                
/* test DrawCircle */
  int blue;
  int red = randomcolor();
  int green = randomcolor();
  int xcord = randomcolor();
  int ycord = randomcolor();
  int myradius = 1;
  for (blue = 0; blue < ((xcord+ycord)/2); blue++) {
    DrawCircle(screen, red, green, blue, myradius, xcord, ycord);
    myradius++;
    }
                                                                                
  sleep(5);
  printf("Quitting SDL.\n");
                                                                                
  return(0);
}

As an exercise, include a random function for generating X and Y coordinates in this program, like the ones below.

It's no fun to see only one circle at the time, so we'll include a while statement that will loop endlessly. To keep it interesting, we relate the radius of the circles with the X and Y coordinates, so that that variable is also a random value. We included these functions:

/* Begin randomx and randomy. */
int randomx() {
  int xcord = rand()/(RAND_MAX/640);
  return(xcord);
}
int randomy() {
  int ycord = rand()/(RAND_MAX/480);
  return(ycord);
}
/* End randomx and randomy. */

The main() function from the previous program is adapted as follows:

int main()
{
  SDL_Surface *screen;
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
  }
  atexit(SDL_Quit);
                                                                                
  screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
    if ( screen == NULL ) {
        fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
        exit(1);
    }
                                                                                
  printf("Set window of 640x480 at %d bits per pixel mode\n",
        screen->format->BitsPerPixel);
                                                                                
/* Set random seed. */
  srandom(time (0));
                                                                                
/* Loop eternally through these 3 circle draws.*/
                                                                                
  while (1) {
                                                                                
    int blue;
    int red = randomcolor();
    int green = randomcolor();
    int myxcord = randomx();
    int myycord = randomy();
    int myradius = 1;
    for (blue=0; blue < (myxcord+myycord)/2; blue++) {
      DrawCircle(screen, red, green, blue, myradius, myxcord, myycord);
      myradius++;
      }
                                                                                
    myradius = 1;
    myxcord = randomx();
    myycord = randomy();
    blue = randomcolor();
    green = randomcolor();
    for (red=0; red < (myxcord+myycord)/2; red++) {
      DrawCircle(screen, red, green, blue, myradius, myxcord, myycord);
      myradius++;
      }
                                                                                
    myradius = 1;
    myxcord = randomx();
    myycord = randomy();
    blue = randomcolor();
    red = randomcolor();
    for (green = 0; green < (myxcord+myycord)/2; green++) {
      DrawCircle(screen, red, green, blue, myradius, myxcord, myycord);
      myradius++;
      }
                                                                                
    }
  sleep(5);
                                                                                
  printf("Quitting SDL.\n");
                                                                                
  return(0);
}

This becomes a bit messy, but if you redeclare variables, you can use the same name in the same program for the same sort of variable, so it is time to clean up a bit before continuing with the next step, making your program react to user input while it is running.

Home
© 1995-2010 Machtelt Garrels - tille - Powered by vIm - Best viewed with your eyes - Validated by W3C - Last update 20100511