Random Numbers

Processing provides a couple of functions for generating random numbers, the most basic being random. The random function has two forms:

float a = random(22.6, 58.2);  // sets a to be a random number that is
                               // greater than, or equal to, 22.6, and
                               // less than (but *not* equal to!) 58.2

float b = random(500.0);   // sets b to be a random number that is
                           // greater than, or equal to, 0.0, and
                           // less than (but *not* equal to!) 500.0

Here’s how you could print 5 random numbers, each from 1 to 10:

int i = 0;
while (i < 5) {
    float r = random(1, 10);
    println(r);
    i += 1;
}

Here’s what one run of this code prints:

7.6910076
1.9692152
7.9845247
1.5725224
6.08494

Every time you run it you will (almost certainly!) get different numbers, e.g.:

3.9555728
8.019813
2.9521606
7.723106
2.4083254

Random Seeds

Sometimes you might want to know what random numbers you will get. You can do this by setting the random number generators seed, e.g.:

randomSeed(2563);
int i = 0;
while (i < 5) {
    float r = random(1, 10);
    println(r);
    i += 1;
}

Here we’ve set the random number seed to be 2563, and so every time you run this code you’ll get the exact same sequence of numbers, namely:

8.817888
3.960303
6.857194
3.9157639
1.8125253

This could be useful, for instance, if you are debugging a game that contains some randomness. By setting a seed with randomSeed, you guarantee you’ll get the same sequence of random values each time.

One other thing: you only call randomSeed at most once, usually in setup. There’s rarely any reason to call it more than once.

Choosing a Random Integer

The random function always returns a float, and so if you want a random integer you must do convert the result to an int like this:

int rand_digit = int(random(10));  //  0 <= random(10) < 10

The int functions converts a float to an int by truncating it, i.e. chopping off any digits after the decimal point. For example:

println(int(2.5));    // prints 2
println(int(9.999));  // prints 9

If you like, you can write a couple of helper functions:

// Returns a random integer that is greater than, or equal to lo,
// and less than (but never equal to!) hi.
int randomInt(int lo, int hi) {
    return int(random(lo, hi));
}

// Returns a random integer that is greater than, or equal to 0,
// and less than (but never equal to!) hi.
int randomInt(int hi) {
    return int(random(0, hi));
}

The name makes it a little more clear what is being returned.

Choosing a Random Character from a String

Suppose you want to choose a random vowel. You could do it like this:

String vowels = "aeiou";
int r = randomInt(vowels.length());
char c = vowels.charAt(r);
println(c);

Notice that the smallest possible value of r is 0, and the largest possible value is vowels.length() - 1. This is exactly the range of index values in the string vowels, so any character in could be printed.

Choosing an Item at Random from an ArrayList

Suppose you want to choose a name at random from an ArrayList of names. You can do it like this:

ArrayList<String> names = new ArrayList<String>();
names.add("Paul");
names.add("John");
names.add("Ringo");
names.add("George");

int r = randomInt(names.size());
String s = names.get(r);
println(s);

If you need to choose a lot of random strings from an ArrayList, then it’s a good idea to put this into a function, e.g.:

String randomString(ArrayList<String> words) {
    int r = randomInt(words.size());
    String s = words.get(r);
    return s;
}

The above code then becomes this:

ArrayList<String> names = new ArrayList<String>();
names.add("Paul");
names.add("John");
names.add("Ringo");
names.add("George");

String s = randomString(names);
println(s);

Example: Random Product Names

Suppose you want to create some randomly named video games. One way to do this is to choose random words at random from some pre-defined lists, e.g.:

ArrayList<String> words1 = new ArrayList<String>();
words1.add("Super");
words1.add("Deluxe");
words1.add("Mega");

ArrayList<String> words2= new ArrayList<String>();
words2.add("Jump");
words2.add("Kitty");
words2.add("Tactical");

ArrayList<String> words3 = new ArrayList<String>();
words3.add("Bomb Squad");
words3.add("Pokemon");
words3.add("War");

String name = randomString(words1) + " " +
              randomString(words2) + " " +
              randomString(words3);

println(name);

This prints names such as:

Mega Tactical Pokemon
Super Kitty Bomb Squad
Deluxe Jump War

Shuffling the Items in an ArrayList

The standard way to shuffle a list of items (i.e. randomly mix them up) is to use the Fisher-Yates shuffling algorithm. Here’s a pseudocode description of how to shuffle an ArrayList<String> called a of n strings:

  • For each value of i, from 0 to n - 1, do the following:
    • j = randomInt(i, n)
    • swap locations of a[i] and a[j]

Here’s an example Processing program that implements it:

ArrayList<String> names = new ArrayList<String>();
names.add("Paul");
names.add("John");
names.add("Ringo");
names.add("George");

// Fisher-Yates shuffle
int i = 0;
while (i < names.size()) {
  int j = randomInt(i, names.size());
  // swap element at location i with element at location j
  String temp = names.get(i);
  names.set(i, names.get(j));
  names.set(j, temp);
  i += 1;
}

for(String s : names) {
  println(s);
}

Again, it’s useful to put this in its own function if you expect it to use it frequently:

void shuffleStrings(ArrayList<String> words) {
  // Fisher-Yates shuffle
  int i = 0;
  while (i < words.size ()) {
    int j = randomInt(i, words.size());
    // swap element at location i with element at location j
    String temp = words.get(i);
    words.set(i, words.get(j));
    words.set(j, temp);
    i += 1;
  }
}

Now you can write code like this:

ArrayList<String> names = new ArrayList<String>();
names.add("Paul");
names.add("John");
names.add("Ringo");
names.add("George");

shuffleStrings(names);

for (String s : names) {
  println(s);
}

Example: Lottery Numbers

Suppose you want to choose lottery ticket numbers at random. In this example, we will see how to choose 7 different numbers chosen from the integers 1 to 49.

Choosing one random integer from 1 to 49 is easily done by calling randomInt(1, 50). But when you choose more numbers, you must make sure that you don’t choose an already chosen number.

To avoid duplicates, we’ll choose the numbers like this:

  1. Create an ArrayList<Integer>, nums, containing the numbers 1, 2, 3, ..., 49.
  2. Shuffle nums.
  3. Print the first 7 numbers of nums.

In Processing this could be coded like this:

ArrayList<Integer> numbers = new ArrayList<Integer>();

// put 1 to 49 into numbers (in order)
int i = 0;
while (i < 49) {
  numbers.add(i);
  i += 1;
}

// mix up the numbers
shuffleInts(numbers);

// print the first 7 numbers
i = 0;
while (i < 7) {
  println(numbers.get(i));
  i += 1;
}

The ShuffleInts function is the same as the shuffleStrings function above, except integers are being shuffled instead of strings:

void shuffleInts(ArrayList<Integer> numbers) {
  // Fisher-Yates shuffle
  int i = 0;
  while (i < numbers.size ()) {
    int j = randomInt(i, numbers.size());
    // swap element at location i with element at location j
    int temp = numbers.get(i);
    numbers.set(i, numbers.get(j));
    numbers.set(j, temp);
    i += 1;
  }
}

Note that you must write ArrayList<Integer> in Processing. Writing ArrayList<int> is an error, the reason being that int is not an object type (it’s a primitive type), and ArrayList only holds object types. Integer is a special class designed specifically to allow ints to be used as if they were objects.

When you run the lottery program, you get results like this:

4
46
44
36
27
34
15

Questions

  1. What is the range of possible values that random(a, a + 5) returns?
  2. Explain what the randomSeed function does.
  3. Write an expression using random whose minimum value is the int 1, and whose maximum value is the int 100.

Programming Questions

  1. Add some more names to the random product name source code. Also, try changing the template for what is printed to get different kinds of names.
  2. Write a program that prints random phone numbers of the form ddd-dddd, where d is a digit.
  3. Modify your answer to the previous question so that the first digit cannot be 0 or 1, and the first 3 digits cannot be 555. This will exclude phone numbers like 083-3993, or 555-1025.

Extra

Here’s an interesting progrma that plots the sum of two randomly-chosen numbers:

ArrayList<Integer> count = new ArrayList<Integer>();

final int N = 100;

void setup() {
  size(400, 500);
  int i = 0;
  while (i < 2 * N) {
    count.add(0);
    ++i;
  }
}

void draw() {
  float a = random(N);
  float b = random(N);
  int ab = int(a + b);
  count.set(ab, count.get(ab) + 1);

  int i = 0;
  while (i < count.size()) {
    line(2 * i, height,
         2 * i, height - map(count.get(i), 0, 200, 0, height)
         );
    ++i;
  }
}

The result is perhaps unexpected: this plots a curve similar in shape to a bell-curve.