1. Understanding Computer-Generated Random Numbers

    A random number is a number whose value cannot be predicted. Many types of programs use random numbers. For example, simulations that predict phenomena such as urban traffic patterns, crop production, and weather systems typically use random numbers. Random numbers also are used in many computer game applications. When you play games with human opponents, their choices are often unpredictable (and sometimes even irrational). Computers usually are predictable and rational, so when you play a game against a computer opponent, you frequently need to generate random numbers. For example, a guessing game would not be very interesting if you were asked to guess the same number every time you played. Most computer programming languages, including Java, come with built-in methods that generate random numbers. The random numbers are calculated based on a starting value, called a seed. The random numbers generated using these methods are not truly random; they are pseudorandom in that they produce the same set of numbers whenever the seed is the same. Therefore, if you seed a random-number generator with a constant, you always receive the same sequence of values. Many computer programs use the time of day as a random-number generating seed. For game applications, this method works well, as a player is unlikely to reset his computer’s clock and attempt to replay a game beginning at exactly the same moment in time. There are two approaches to generating random numbers in Java. Both techniques are explained in this appendix and summarized in Table.
    Math.random() methodYou do not need to create an object.
    You do not need to understand constructors and multiple methods.
    Random class and its methodsYou can generate numbers in the format you need without arithmetic manipulation. You can create reproducible results if necessary.
  2. Using the Math.random() Method

    Java’s Math class provides a random() method that returns a double value in the range of 0.0 up to, but not including, 1.0. For example, the application in Figure generates three random numbers and displays them. Figure D-2 shows three successive executions of the program.
    public class SomeRandomNumbers { public static void main (String[] args) { double randomNumber; randomNumber = Math.random(); System.out.println(randomNumber); randomNumber = Math.random(); System.out.println(randomNumber); randomNumber = Math.random(); System.out.println(randomNumber); } }
    The values displayed in Figure appear to be random, but they are not typical of the values you need in a game-playing program. Usually, you need a relatively small number of whole values. For example, a game that involves a coin flip might only need two values to represent heads or tails, and a dice game might need only six values to represent rolls of a single die. Even in a complicated game in which 40 types of space aliens might attack the player, you need only 40 whole numbers generated to satisfy the program requirements. For example, suppose you need a random number from 1 to 10. To change any value generated by the Math.random() method to fall between 0 and 10, you can multiply the generated number by 10. For example, the last three numbers in Figure D-2 would become approximately 0.5, 6.6, and 9.3. Then, you can eliminate the fractional part of each number by casting it to an int; after this step, every generated number will be a value from 0 to 9 inclusive. Finally, you can add 1 to a value so it falls in the range from 1 to 10 instead of 0 to 9. In short, the following statement generates a random number from 1 through 10 inclusive, and assigns it to randomNumber: int randomNumber = 1 + (int)(Math.random() * 10); Suppose that, instead of 1 through 10, you need random numbers from 1 through 13. (For example, standard decks of playing cards have 13 values from which you might want to select.) When you use the modulus operator (%) to find a remainder, the remainder is always a value from 0 to one less than the number. For example, if you divide any number by 4, the remainder is always a value from 0 through 3. Therefore, to find a number from 1 through 13, you can use a statement like the following: int ranCardValue = ((int)(Math.random() * 100) % 13 + 1); In this statement, a randomly generated value (for example, 0.447) is multiplied by 100 (producing 44.7). The result is converted to an int (44). The remainder after dividing by 13 is 5. Finally, 1 is added so the result is 1 through 13 instead of 0 through 12 (giving 6). In short, the general format for assigning a random number to a variable is: int result = ((int)(Math.random() * 100) % HIGHEST_VALUE_WANTED + LOWEST_VALUE_WANTED);
  3. Using the Random Class
    The Random class provides a generator that creates a list of random numbers. To use this class, you must use one of the following import statements: import java.util.*; import java.util.Random; You also must instantiate a random-number generator object using one of the following constructors: • Random(), in which the seed comes from the operating system; this constructor sets the seed of the random-number generator to a value that is probably distinct from any other invocation of this constructor • Random(long seed), in which you provide a starting seed so that your results are reproducible After you create a random-number generator object, you can use any of the methods in Table to get the next random number from the generator.
    nextInt(int n)Returns a pseudorandom int value between 0 (inclusive) and the specified value n (exclusive), drawn from the random-number generator’s sequence
    nextInt()Returns a pseudorandom int value between 0 (inclusive) and 1.0 (exclusive), drawn from the random-number generator’s sequence
    nextLong()Returns the next pseudorandom long value from the generator’s sequence
    nextFloat()Returns the next pseudorandom float value between 0.0 and 1.0 from the generator’s sequence
    nextDouble()Returns the next pseudorandom double value between 0.0 and 1.0 from the generator’s sequence
    nextBoolean()Returns the next pseudorandom boolean value from the generator’s sequence
    For example, Figure contains an application that declares a Random generator named randomNumber, using the version of the constructor that takes no arguments. This ensures that the results are different each time the application runs. The program then defines LIMIT as 10, and calls randomNumber.nextInt(LIMIT) three times, displaying the results
    import java.util.*; public class SomeRandomNumbers2 { public static void main(String[] args) { Random randomNumber = new Random(); final int LIMIT = 10; System.out.print(randomNumber.nextInt(LIMIT) + " "); System.out.print(randomNumber.nextInt(LIMIT) + " "); System.out.println(randomNumber.nextInt(LIMIT)); } }
    Figure shows a class using the version of the Random constructor that takes an argument. In this example, a value between 0 and 6 inclusive is generated 15 times.
    import java.util.*; public class SomeRandomNumbers3 { public static void main(String[] args) { Random randomNumber = new Random(129867L); final int TIMES = 15; final int LIMIT = 7; for(int x = 0; x < TIMES; ++x) System.out.print(randomNumber.nextInt(LIMIT) + " "); System.out.println(); } }