Never the Same Number Twice

One of the most common questions I get from my For Dummies programming titles is regarding the lotto programs. That code demonstrates how you can randomly draw lotto balls without drawing the same ball twice.

In programming, specifically for games, you’ll find situations where you don’t want the same random number popping up again. For example, when drawing cards from a deck, you don’t want the code to suddenly draw two 7♣ cards. That would most likely piss off the player.

Likewise, you don’t want to have a lotto drawing where the 23 ball shows up twice or thrice or whatever-the-ice-thing-for-four-is.

To prevent such misfortune, you need to keep track of the random numbers generated. But first, to illustrated the problem, here is some code that generates 50 random numbers in the range 1 through 8:

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

#define RANGE 8
#define COUNT 50

int main()
{
    int x;
    long r;

    srandom((unsigned)time(NULL));      /* seed randomizer */

    for(x=0;x<COUNT;x++)
    {
        r = random() % RANGE + 1;
        printf("%ld ",r);
    }
    putchar('\n');

    return(0);
}

Sample output:

7 3 5 6 5 7 6 3 5 5 3 7 4 2 5 7 3 1 1 4 2 3 6 4 2 6 4 5 6 5 3 4 7 7 2 3 5 7 5 2 3 7 8 7 1 5 5 3 5 5

As you can see, lots of duplicates are generated.

The program can be re-coded to count the number of duplicates. To do that, you’d need to create an array in the same range as the random values. In this case, that would be 1 through 8. Each time a random value is drawn, the array element for that value is incremented.

For example, if the value 5 were drawn, array[5] would be incremented: array[5]++. That way you can keep count of the values generated, pairing the random values with array elements:

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

#define RANGE 8
#define COUNT 50

int main()
{
    int x;
    long r,array[RANGE];

    srandom((unsigned)time(NULL));      /* seed randomizer */

    for(x=0;x<RANGE;x++)                /* initialize the array */
        array[x] = 0L;

    for(x=0;x<RANGE;x++)                /* table heading */
        printf("%d\t",x+1);
    putchar('\n');

    for(x=0;x<COUNT;x++)                /* Generate COUNT random values */
    {
        r = random() % RANGE;           /* get random value */
        array[r]++;                     /* count that value */
    }

    for(x=0;x<RANGE;x++)                /* display results */
        printf("%ld\t",array[x]);
    putchar('\n');

    return(0);
}

Here’s the sample output:

1	2	3	4	5	6	7	8	
7	6	6	6	3	10	7	5

In this example, the value one was generated 7 times. The value six was the most popular, being generated 10 times. The array keeps track of each random value at Line 25 in the code:

array[r]++;

The random value generated, r, references an array element r. Incrementing the array element’s value is how you count which random value was produced.

Here is another modification to the code, one that dynamically displays which values are generated:

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

#define RANGE 8
#define COUNT 50

int main()
{
    int x,y;
    long r,array[RANGE];

    srandom((unsigned)time(NULL));      /* seed randomizer */

    for(x=0;x<RANGE;x++)                /* initialize the array */
        array[x] = 0L;

/* dipslay the array's contents each time a random value is generated */

    for(x=0;x<COUNT;x++)                /* Generate COUNT random values */
    {
        r = random() % RANGE;           /* get random value */
        array[r]++;                     /* count that value */
        for(y=0;y<RANGE;y++)            /* display array */
            printf("%ld\t",array[y]);
        putchar('\n');
    }

    return(0);
}

The output shows how each random value is drawn, one at a time. Here are the first few lines of sample output:

0	0	0	0	0	0	1	0	
1	0	0	0	0	0	1	0	
2	0	0	0	0	0	1	0	
2	0	0	0	0	0	2	0	
2	0	0	0	0	1	2	0	
2	0	0	0	0	1	3	0	
2	1	0	0	0	1	3	0

All values in the array are initialized to zero (Lines 15 and 16 in the code). Therefore, the first value drawn shows up as a 1. It’s seven in the sample output above.

The second value drawn is one. The third value drawn is also one, which increments that column’s value to 2. Then a seven is drawn again. Then a six, then another seven, then a two.

As you scroll through the program’s output on yoru machine, you can see how the random numbers drawn cascade through the array.

Next week I’ll unravel the puzzle of how to monitor the random values generated and prevent the same value from being drawn twice.

Leave a Reply