Skip to Content
Course content

91: Generating Random Numbers with rand and srand

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Alright, let's try to build something simple: a digital six-sided die for a tabletop game. It sounds trivial, but C handles "randomness" in a way that often trips people up the first time they touch it. I'll walk you through how I usually figure this out when I've forgotten the specifics.

The "Wait, Why Is This the Same?" Moment

First instinct? Just call rand(). I'll throw together a quick loop to simulate rolling a die five times and see what we get.

#include <stdio.h>
#include <stdlib.h>

int main() {
    for(int i = 0; i < 5; i++) {
        printf("%d ", rand());
    }
    return 0;
}

I run this, and I get: 41 18467 6334 26500 789. Okay, looks random enough. But here's the weird part—I run the program again, and I get 41 18467 6334 26500 789 again. And again. Every single time.

This is because rand() isn't actually random; it's a pseudo-random number generator. It uses a mathematical formula to produce a sequence of numbers. That formula starts with a "seed" value. If the seed is always the same (which it is by default), the sequence will be identical every time you launch the app. That's great for debugging a bug in a specific sequence, but terrible for a game.

Planting a Seed

To fix this, I need to change the seed. C gives us srand() (short for seed-rand) for this. I'll try giving it a hardcoded number just to see if it changes the output.

srand(123); // Planting a seed of 123
for(int i = 0; i < 5; i++) {
    printf("%d ", rand());
}

Now I get a different sequence than before, but if I run the program again, I still get that same new sequence. Using a hardcoded number just swaps one predictable sequence for another. To make it feel truly random to the user, I need a seed that changes every time the program starts. The easiest way? The current system time.

I'll pull in <time.h> and use time(NULL), which returns the number of seconds since the Epoch. Since that number is always increasing, the seed will be different every time you hit "Run".

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL)); // Seed based on current time
    for(int i = 0; i < 5; i++) {
        printf("%d ", rand());
    }
    return 0;
}

Now, every time I run it, I get a totally different set of numbers. We've solved the predictability problem.

Squeezing the Range

The problem now is that rand() returns massive integers—anywhere from 0 up to RAND_MAX (which is at least 32,767). I can't use a number like 26,500 for a six-sided die. I need a way to "clamp" this value.

I'll use the modulo operator %. If I take rand() % 6, the remainder will always be between 0 and 5. But a die is 1 to 6, not 0 to 5. A simple + 1 shift fixes that.

int roll = (rand() % 6) + 1;

I'll put it all together now. I'll wrap the roll in a function to keep the main clean. One quick tip: notice I only call srand() once at the very start of the program. A common mistake is putting srand() inside a loop. If you do that, and the loop runs fast enough, time(NULL) will return the same second for every iteration, and you'll end up with the same "random" number repeated five times. Always seed once, then harvest as many numbers as you need.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int roll_die() {
    return (rand() % 6) + 1;
}

int main() {
    srand(time(NULL));

    printf("Rolling the dice...\n");
    for(int i = 0; i < 3; i++) {
        printf("Roll %d: %d\n", i + 1, roll_die());
    }

    return 0;
}



📋 Practical Task

Build a Critical Hit Simulator

Write a program that simulates a combat encounter in a game. The program should perform the following:

  • Seed the random number generator using the current time.
  • Generate a random number between 1 and 100 to represent an "attack roll".
  • If the roll is 95 or higher, print "CRITICAL HIT!" and a bonus damage value (a random number between 20 and 50).
  • If the roll is between 1 and 94, print "Normal Hit" and a standard damage value (a random number between 5 and 19).

Make sure your damage ranges are calculated correctly using the (rand() % range) + offset logic we discussed.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.