# The Random Class.

## Presentation on theme: "The Random Class."— Presentation transcript:

The Random Class

Topics •Random numbers •Random number generators •Uniform and non-uniform distributions •The Random class •Seeds for Random() •Tossing dice •Picking passwords

Random Numbers Programs frequently need random numbers. A card game uses random numbers to create a shuffled deck of cards. A dice game uses random numbers to simulate a throw. Many activities in the real world (such as traffic on a highway system) appear to be random, and a program that models them must use random numbers. This chapter discusses the Random class that comes with Java.

Random Numbers Random numbers, probability, and statistics are important for testing, for modeling the world, and for general understanding of the universe. Computer science degree programs usually require a course in these subjects.

What number is most likely outcome
Question #1 What number is most likely outcome for a throw of a fair die?

Random Numbers A single die can be regarded as a random number generator that selects a number from the range 1 through 6, and each number is equally likely. The same is true for a second throw of the die. The outcome of the first throw does not affect the outcome of the second throw (or of any other throw). If you throw a die many times, you will get a sequence of random numbers. Since each number is equally likely, you would expect each number to occur about as often as any other number. For example, if you threw the die 60 times, you would expect to see about 10 of each number. However, it would be unusual to see exactly 10 of each number. The die does not "remember" its previous outcomes and does nothing to catch up with numbers they may have fallen short.

QUESTION 2: A game spinner (say) has 12 divisions, numbered 1 through 12. Which number is most likely?

Uniform Distribution When each number in a range of numbers is equally likely, the numbers are uniformly distributed. Many random number generators, such as a single die or a spinner, produce a uniform distribution. However, some random number generators are not uniform. For example, when two dice are thrown and the outcome is the sum of the spots, the range of possible outcomes is 2 through 12, but 7 is the most likely outcome since there are 6 combinations that sum to 7, more than any other number. Six and 8 are the second most likely outcomes, since there are 5 combinations each that sum to those numbers.

Question 3 What are the least likely outcomes from a pair of dice?
(Hint: study the table.)

The Random Class The Random class can be used in programs that need random numbers. Random is part of the java.util package. The numbers that Random generates are actually pseudorandom, because they are calculated using a formula. But they appear to be random and can be used in most situations that call for random numbers. A Random object is started out with a seed value which determines the sequence of numbers it will produce. Every Random object started with the same seed value will produce the same sequence of numbers. There are two constructors for Random objects:

The Random Class Random() — Creates a new random number generator using a seed based on the current time. Random( long seed ) — Creates a new random number generator based on a specific seed value. The first constructor uses a seed value based on the current time in milliseconds. Use it when you need a different stream of random numbers for each run of the program. For example, a game program that uses random numbers to simulate a shuffled deck of cards needs a different stream each time the game is played. The second constructor gives you the ability to repeat a pseudorandom sequence. Use it when you need to test different strategies against the same stream of random events.

Random rand = new Random();
The Random Class Here is an example of constructing a random number generator: Random rand = new Random(); Now the methods of the Random class can be used with rand.

Question #4 Are there situations where you do want to use
the exact same "random" sequence for several runs of a program?

nextInt() Here are two methods (out of several) that Random objects provide. The second method is the one most often used. num must be a positive integer. The random integers are selected from the range 0 up to and including num-1 but not including num. int nextInt() — Returns the next pseudorandom, uniformly distributed int value. All possible int values, both positive and negative, are in the range of values returned. int nextInt( int num ) — Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and num (exclusive).

How can nextInt( int num ) be used for that?
Question #5 Say that you want pseudorandom numbers selected from the range 1 through 6. How can nextInt( int num ) be used for that?

Die Toss Program The trick is to determine how many integers are in the range of outcomes you want, and use that as the parameter to nextInt(). Then add the minimum value of the range you want. In this example we want 1,2,3,4,5,6 so the number of outcomes is 6. nextInt(6) will output numbers from 0,1,2,3,4,5 so add one to get the desired range. Here is a program that simulates tossing a die. import java.util.Random; import java.util.Scanner; public class DieToss { public static void main ( String[] args ) Scanner scan = new Scanner( System.in ); Random rand = new Random( ); while ( true ) System.out.print("You toss a " + (rand.nextInt(6)+1) ); String line = scan.nextLine(); }

Die Toss Program The statement: Random rand = new Random();
creates a random number generator using a seed based on the current time. The program will produce a different sequence of numbers each time it is run. The while loop runs until the user hits control-C (or otherwise kills the program). The loop body selects a random number from the range 1 through 6 and prints it out: System.out.print("You toss a " + (rand.nextInt(6)+1) ); Then the loop body waits until the user hits "enter". (Actually, any line ending with "enter" would work.) String line = scan.nextLine(); Nothing is done with the line the user types; it is just used to pause the output. (You could improve the program by having it end gracefully when the user types "Q" or "q".)

Question #6 Say that you want random integers in
The range -5 to +5 (inclusive). How can you use nextInt() for that? (Hint: see the previous answer.)

Example Output Here is a run of the die-tossing program:
K:\cai\>java DieToss You toss a 2 You toss a 1 You toss a 4 You toss a 6 You toss a 5 You toss a 3 You toss a 2Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Unknown Source) at DieToss.main(DieToss.java:15) The user hit control-C to end the program.

Question #7 (Thought Question: )
You want to simulate the toss of two dice. Do you need two random number generators?

Two-dice Gotcha! In fact, if you use two random number generators, you need to be careful. The following code: Random rand1 = new Random(); Random rand2 = new Random(); will most likely produce two random number generators which are initialized to the same seed. Each generator would then produce the same pseudorandom sequence. This is not what you want. The reason this happens is because the constructor Random() creates a seed based on the current time in milliseconds. Time changes little between the execution of the two statements, so both random number generators use the same seed. Two generators started with the same seed generate the same sequence of pseudorandom numbers. You could initialize the second random number generator using a random number from the first, but it is more convenient to use just one random number generator.

Do you ever need more than one random number generator?
Question #8 Do you ever need more than one random number generator?

Two-dice Program Here is a program that simulates the toss of two dice: import java.util.*; public class TwoDieToss { public static void main ( String[] args ) Scanner scan = new Scanner( System.in ); Random rand = new Random(); while ( true ) System.out.print("You toss a " + (rand.nextInt(6)+1 + rand.nextInt(6)+1) ); String input = scan.nextLine(); }

(rand.nextInt(6)+1 + rand.nextInt(6)+1)
Two-dice Program The two tosses and the sum of the spots is implemented in the expression: (rand.nextInt(6)+1 + rand.nextInt(6)+1) Each call to nextInt(6) is completely independent of the previous call, so this is the same as throwing two independent dice. Throwing one die twice and adding up each outcome is equivalent to throwing two dice and adding up each die. However, throwing a 12-sided die once is not equivalent to throwing two 6-siced dice.

Would the following work to simulate two dice:
Question #9 Would the following work to simulate two dice: (rand.nextInt(11)+2)

Example Output Here is a sample run of the above (correct) program:
You toss a 11 You toss a 8 You toss a 6 You toss a 5 You toss a 12 You toss a 4 You toss a 5 Exception in thread "main" . . .

Here is a sample run of a program that (incorrectly) uses:
Example Output Here is a sample run of a program that (incorrectly) uses: (rand.nextInt(11)+2) You toss a 6 You toss a 10 You toss a 11 You toss a 4 You toss a 5 You toss a 9 You toss a 7 You toss a 2 You toss a 3 Exception in thread "main" . . .

Example Output With such a small sample, you can't tell for sure that something is wrong, but you might be suspicious. To confirm your suspicions, gather much more data, then count the number of times each outcome occurs and check that the results match what you expect. This is part of what is studied in a probability and statistics course.

Would you ever need a random floating point value?
Question #10 Would you ever need a random floating point value?

Floating Point Random Methods
Here are some more methods of the Random class: float nextFloat() — Returns a pseudorandom, floating point value in the range 0.0 up to but not including 1.0. double nextDouble() — Returns a pseudorandom, double-precision value in the range 0.0 up to but not including 1.0. double nextGaussian() — Returns a pseudorandom, double-precision value drawn from a Gaussian distribution (also called a "normal" distribution or a "bell-shaped curve".) The mean of the distribution is 0.0 and the standard deviation is 1.0.

Floating Point Random Methods
Notice that nextFloat() and nextDouble() output random floating point values in the range [0.0, 1.0), all values starting at zero, up to but not including 1.0. You might think that it is strange not to include 1.0, but this is actually convenient, and is what is done by nearly all floating point random number generators. To visualize a random floating point generator, think of a spinner centered on a circle with a circumference of one foot. To generate a random float, spin the pointer, then measure the distance along the circle, from the zero mark. Measure the distance using "hundredths of a foot". The distance is the randomly selected float in hundredths. If the circumference is exactly one foot, then the "0.0" mark on the circle and the "1.0" mark on the circle would be the same. This might be awkward. But 1.0 is excluded from the range so the problem is avoided.

Question #11 Say that you want random doubles in
the range 0.0 up to (but not including) 10.0. How can you get that range using nextDouble()?

Calculator Tester Say that you are not convinced that Java and your electronic calculator give the same results for sin(x). You could test this by checking the values each produces for some standard angles, such as 0.0, pi/2 and so on. But you should also test several randomly selected angles. Here is a program that calculates sin(x) for random angles (in radians) between -10*pi and +10*pi.

Calculator Tester import java.util.Random; class SineTester {
public static void main ( String[] args ) int j=0; Random rand = new Random(); System.out.println(" x " + "\t\t\t sin(x)"); while ( j<10 ) double x = rand.nextDouble()*(20*Math.PI) - 10*Math.PI; System.out.println("" + x + "\t" + Math.sin(x)); j = j+1; }

Calculator Tester Random values are often used for testing. Sometimes things work perfectly for standard values, but not for random ones. For example, some gas stations in California adjusted their pumps to dispense exactly the correct amount of fuel for multiples a half gallon, but to dispense less fuel for all other amounts. The Bureau of Weights and Measures tested the pumps at standard volumes (half a gallon, one gallon, ten gallons and such) so the pumps passed inspection. Testing random volumes would have revealed the scam.

Might you ever need to simulate flipping a coin?
Question #12 Might you ever need to simulate flipping a coin?

More Random Methods Here are some more methods of the Random class:
long nextLong() — Returns a pseudorandom, uniformly distributed long value. All possible long values, both positive and negative, are in the range of values returned. boolean nextBoolean() — Returns a pseudorandom boolean value. void setSeed(long seed) — sets the seed of the random number generator. This might be done in several places in a program so that different objects are tested against the same random events. There are some other methods of Random not described here.

Question #13 Think of a really great secret password for your computer account.

Sounds like you need to consult Nigerian Security Services, Ltd.

The details of this program are explained in the next few pages.

Question #14 What is the purpose of the following loop from the program: while ( digits < 5 ) { System.out.println("Your password must have at least 5 characters."); System.out.print("How many characters do you want in your password? "); digits = scan.nextInt(); }

"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
String of Characters Next, the program assembles a string of all the characters that could go into a password: String choices = "abcdefghijklmnopqrstuvwxyz”; choices = choices + choices.toUpperCase(); choices = choices + " " ; The first of these three statements creates a string literal containing the lower case alphabet. Then the expression choices.toUpperCase() creates a string that is all upper case, based on the string currently referred to by choices. This string is then concatenated onto the original choices string: Recall that + means "string concatenation". Finally, the string " " is concatenated onto the string to produce the final string, shown below: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "

Question #15 Would the statement: have worked as well?
choices = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "; have worked as well?

String password = ""; int j = 0; while ( j<digits ) { password = password + choices.charAt( rand.nextInt( choices.length() ) ); j = j + 1; }

rand.nextInt( choices.length() )
Building the Password First the password is initialized to the empty string. Then random characters, selected from choices, are appended to it, one-by-one. The expression: rand.nextInt( choices.length() ) randomly picks an integer from 0 up to (but not including) the length of the choices string. Then that integer is used to select a character from the choices string. Say that the random integer were 7. Then choices.charAt( 7 ) is character number 7 in the string choices, where counting starts at zero. This character is appended to the password and the loop repeats. (For more about string methods, see chapter 29.)

Question #16 Examine this statement:
password = password + choices.charAt( rand.nextInt( choices.length() ) ); Four things happen in that one statement. This can be hard to keep track of. Is the following code fragment equivalent? int range = choices.length(); int characterNumber = rand.nextInt( range ); char ch = choices.charAt( characterNumber ); password = password + ch;

Dice Game Here are the rules to a dice game:
The game consists of several "rounds." In each round, the computer plays first by throwing two six-sided dice and adding the spots. The player must now try to beat that sum. The player may choose to throw two six-sided dice or one 11-sided die (with sides numbered 2-12). If the player's throw beats the computer, then the player wins the round. Otherwise the computer wins the round. The game continues until either the player or the computer has won ten rounds. The player can chose to throw two dice, which randomly select a number 2 through 12, or to throw the 11-sided die, which also randomly selects a number 2 through 12. But the distribution of numbers is different for each choice.

Dice Game Here are the first four rounds of a game:
The Computer tosses: 10 Toss 1 eleven-sided die, or 2 six-sided dice (enter 1 or 2)? 1 You throw 1 die and get: 7 You loose the round! Score: computer 1, you 0 The Computer tosses: 4 Toss 1 eleven-sided die, or 2 six-sided dice (enter 1 or 2)? 2 You throw 2 dice and get: 9 You win the round! Score: computer 1, you 1 You throw 1 die and get: 3 Score: computer 2, you 1 The Computer tosses: 5 You throw 2 dice and get: 5 Score: computer 3, you 1

Dice Game Eleven-sided dice are hard to find in the real world. If you want to play this game with physical dice use a twelve-sided or sixteen-sided die (which do exist, ask any Dungeon Master) and discard rolls other than 2 through 12.

Question #17 What advantage does the computer have in this game?
What advantage does the player have in this game?

What advantage does the computer have in this game?
The computer's throw must be beaten by the player. In case of a tie, the computer wins the round. What advantage does the player have in this game? The player can select from a uniform distribution (one 11-sided die) or a non-uniform distribution (two regular dice) with as the most common outcomes. Use the uniform distribution when a high number is needed; use the non-uniform distribution when is enough to win a round. Is this enough to overcome the computer's advantage? Play the game and see!

Flow Chart Here is the main logic of the program. Study how it implements the rules of the game. Some additional details are needed for some of the steps. The "Player's Toss" box, for one, needs to implement the details of giving the player a choice of dice and then throwing that choice.

How many random number generators are needed for this program?
Question #18 How many random number generators are needed for this program?

Complete Program Here is the complete program. Its sections will be explained shortly. The sections of the program match the boxes in the flowchart. You can copy and paste this program to a file and play with it, if you want. import java.util.*; class DiceChoiceGame { public static void main ( String[] args ) { // Declare and Initialize final int endScore=10; Scanner scan = new Scanner( System.in ); Random rand = new Random(); int playerScore=0, compScore=0; int playerToss, compToss; // Play Rounds until one player reaches ending score while ( playerScore<endScore && compScore<endScore ) { // Computer's Toss compToss = rand.nextInt(6)+1 + rand.nextInt(6)+1 ; System.out.println("The Computer tosses: " + compToss); // Player's Toss System.out.print("Toss 1 eleven-sided die, or 2 six-sided dice (enter 1 or 2)? "); String numDice = scan.nextLine(); if ( numDice.equals("1") ) { playerToss = rand.nextInt(11)+2 ; System.out.println("You throw 1 die and get: " + playerToss ); } else { playerToss = rand.nextInt(6)+1 + rand.nextInt(6)+1 ; System.out.println("You throw 2 dice and get: " + playerToss ); } // Determine Winner of Round and Adjust Scores if ( playerToss>compToss ) { playerScore = playerScore+1; System.out.println("You win the round!"); } else { compScore = compScore+1; System.out.println("You loose the round!"); } System.out.println("Score: computer " + compScore + ", you " + playerScore + "\n"); } // Determine Winner of the Game System.out.println("Final Score: computer " + compScore + ", you " + playerScore); if ( compScore > playerScore ) System.out.println("The Computer Wins!"); else System.out.println("You Win the Game!"); } }

Will one player or the other eventually win?
Question #19 Will one player or the other eventually win? Or is a draw possible?

Main Loop Here is the logic that implements the main loop:
// Declare and Initialize final int endScore=10; int playerScore=0, compScore=0; // Play Rounds until one player reaches ending score while ( playerScore<endScore && compScore<endScore ) { } The body of the loop corresponds to one round of the game.

(Review: ) What does final int endScore=10; do?
Question #20 (Review: ) What does final int endScore=10; do?

The Tosses The computer's toss is straightforward. This is just summing up the toss of two individual six-sided dice. // Computer's Toss compToss = rand.nextInt(6)+1 + rand.nextInt(6)+1 ; System.out.println("The Computer tosses: " + compToss); For the user's toss, first the program asks the user which dice to use: // Player's Toss System.out.print("Toss 1 eleven-sided die, or 2 six-sided dice (enter 1 or 2)? "); String numDice = scan.nextLine();

The Tosses No numerical use is made of the digit that the user types, so it is best to read it in as a string. That way if the user accidentally hits a non-digit the program will not crash. String comparison is then used to determine which option to take. Everything but digit "1" will result in the two-dice branch. if ( numDice.equals("1") ) { playerToss = rand.nextInt(11)+2 ; System.out.println("You throw 1 die and get: " + playerToss ); } else playerToss = rand.nextInt(6)+1 + rand.nextInt(6)+1 ; System.out.println("You throw 2 dice and get: " + playerToss );

Question #21 Wouldn't it be better to test if the user types
exactly the specified choices?

Determining the Winner of the Round
The final code in the loop body determines the winner of the round: // Determine Winner of Round and Adjust Scores if ( playerToss > compToss ) { playerScore = playerScore+1; System.out.println("You win the round!"); } else compScore = compScore+1; System.out.println("You loose the round!"); System.out.println("Score: computer " + compScore + ", you " + playerScore + "\n"); There is nothing difficult here, but notice that the code is written so that the computer wins when the dice tosses are equal.

Question #22 As another exercise, you could add code to do something else when the tosses are equal.