This material is licensed under the Creative Commons BY-NC-SA license, which means that you can use it and distribute it freely so long as you do not erase the names of the original authors. If you make changes in the material and want to distribute this altered version of the material, you have to license it with a similar free license. The use of the material for commercial use is prohibited without a separate agreement.
Authors: Arto Hellas, Matti Luukkainen
Translators to English: Emilia Hjelm, Alex H. Virtanen, Matti Luukkainen, Virpi Sumu, Birunthan Mohanathas, Etiënne Goossens
Extra material added by: Etiënne Goossens, Maurice Snoeren, Johan Talboom
The course is maintained by Technische Informatica Breda
When programming, you may occasionally need to simulate random events. Situations such as the unpredictability of weather, or surprising moves on the AI’s part in a computer game can often be simulated with random number generators, running on a computer. In Java, there is a ready-made class Random
, which you can use in the following way:
import java.util.Random;
public class Randomizing {
public static void main(String[] args) {
Random randomizer = new Random(); // creates a random number generator
int i = 0;
while (i < 10) {
// Generates and prints out a new random number on each round of the loop
System.out.println(randomizer.nextInt(10));
i++;
}
}
}
In the code above, you first create an instance of the class Random
with the keyword new
– exactly as when creating objects implementing other classes. An object of type Random has the method nextInt
that can be given an integer value as parameter. The method returns a random integer within the range 0..(the integer given as parameter- 1).
The printout of this program could be as follows:
2
2
4
3
4
5
6
0
7
8
We will need floating point numbers, for example when dealing with probability calculations. In computing, probabilities are usually calculated with numbers within the range [0..1]. An object of the class Random can return random floating point numbers with the method nextDouble
. Let us consider the following probabilities of weather conditions:
Using the estimates above, let us create a weather forecaster.
import java.util.ArrayList;
import java.util.Random;
public class WeatherForecaster {
private Random random;
public WeatherForecaster() {
this.random = new Random();
}
public String forecastWeather() {
double probability = this.random.nextDouble();
if (probability <= 0.1) {
return "Sleet";
} else if (probability <= 0.4) { // 0.1 + 0.3
return "Snow";
} else { // the rest, 1.0 - 0.4 = 0.6
return "Sunny";
}
}
public int forecastTemperature() {
return (int) ( 4 * this.random.nextGaussian() - 3 );
}
}
The method forecastTemperature
is interesting in many ways. Within this method, we are calling the method this.random.nextGaussian()
, just like any other time we have called a method in the previous examples. Interestingly, this method of the class Random
returns a value from the normal distribution (if you have no interest in the different varieties of random figures, that’s okay!).
public int forecastTemperature() {
return (int) ( 4 * this.random.nextGaussian() - 3 );
}
In the expression above, interesting is the section (int
). This part of the expression changes the bracketed floating point number into an integer value. A corresponding method transforms integer values into floating point numbers: (double
) integer. This is called an explicit type conversion.
Let us create a class with a main method that uses the class WeatherForecaster
.
public class Program {
public static void main(String[] args) {
WeatherForecaster forecaster = new WeatherForecaster();
// Use a list to help you organise things
ArrayList<String> days = new ArrayList<String>();
Collections.addAll(days, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
System.out.println("Weather forecast for the next week:");
for(String day : days) {
String weatherForecast = forecaster.forecastWeather();
int temperatureForecast = forecaster.forecastTemperature();
System.out.println(day + ": " + weatherForecast + " " + temperatureForecast + " degrees.");
}
}
}
The printout from this program could be as follows:
Weather forecast for the next week:
Mon: Snow 1 degrees.
Tue: Snow 1 degrees.
Wed: Sunny -2 degrees.
Thu: Sunny 0 degrees.
Fri: Snow -3 degrees.
Sat: Snow -3 degrees.
Sun: Sunny -5 degrees.
Exercise random-1: Rolling the dice
In the template is class Dice that has the following functionality:
- The constructor
Dice(int numberOfSides)
creates a new dice object that has the amount of sides defined by the argument.- The method
roll
tells the result of a roll (which depends on the number of its sides)The frame of the program is as follows:
import java.util.Random; public class Dice { private Random random; private int numberOfSides; public Dice(int numberOfSides){ this.numberOfSides = numberofSides; random = new Random(); } public int roll() { // we'll get a random number in the range 1-numberOfSides< } }
Expand the class
Dice
so that with each roll the dice returns a random number between1...number
of sides. Here is a main program that tests the dice:public class Program { public static void main(String[] args) { Dice dice = new Dice(6); int i = 0; while ( i < 10 ) { System.out.println( dice.roll() ); i++; } } }
The output could look something like this:
1 6 3 5 3 3 2 2 6 1
Exercise random-2: Password randomizer
Your assignment is to expand the class
PasswordRandomizer
that has the following functionality:The constructor PasswordRandomizer creates a new object, which uses the given password length. The method createPassword returns a new password, which consists of symbols a-z and is of the length given as a parameter to the constructor The frame of the class is as follows:
import java.util.Random; public class PasswordRandomizer { // Define the variables here public PasswordRandomizer(int length) { // Format the variable here } public String createPassword() { // Write the code here which returns the new password } }
In the following is a program that uses a PasswordRandomizer object:
public class Program { public static void main(String[] args) { PasswordRandomizer randomizer = new PasswordRandomizer(13); System.out.println("Password: " + randomizer.createPassword()); System.out.println("Password: " + randomizer.createPassword()); System.out.println("Password: " + randomizer.createPassword()); System.out.println("Password: " + randomizer.createPassword()); } }
The output could look something like this:
Password: mcllsoompezvs Password: urcxboisknkme Password: dzaccatonjcqu Password: bpqmedlbqaopq
Tip 1: this is how you turn the integer number into a character:
int number = 17; char symbol = "abcdefghijklmnopqrstuvwxyz".charAt(number);
Tip 2: The tip in assignment 58 might be useful in this one too.
Exercise random-3: Lottery
Your assignment is to expand the class
LotteryNumbers
, which draws the lottery numbers of the week. The numbers of the week consist of 7 different numbers between 1 and 39. The class has the following functionality:
- the constructor
LotteryNumbers
creates a new LotteryNumbers object, which contains the new drawn numbers- the method
numbers
returns the drawn numbers of this draw- the method
drawNumbers
draws new numbers- the method
containsNumber
reveals if the number is among the drawn numbersThe frame of the class is as follows:
import java.util.ArrayList; import java.util.Random; public class LotteryNumbers { private ArrayList<Integert> numbers; public LotteryNumbers() { // We'll format a list for the numbers this.numbers = new ArrayList<Integert>(); // Draw numbers as LotteryNumbers is created this.drawNumbers(); } public ArrayList<Integert> numbers() { return this.numbers; } public void drawNumbers() { // Write the number drawing here using the method containsNumber() } public boolean containsNumber(int number) { // Test here if the number is already among the drawn numbers } }
The following main program comes with the template:
import java.util.ArrayList; public class Program { public static void main(String[] args) { LotteryNumbers lotteryNumbers = new LotteryNumbers(); ArrayList<Integert> numbers = lotteryNumbers.numbers(); System.out.println("Lottery numbers:"); for (int number : numbers) { System.out.print(number + " "); } System.out.println(""); } }
The program can print lines like these:
Lottery numbers: 3 5 10 14 15 27 37
Lottery numbers: 2 9 11 18 23 32 34
Note! a number can be in one set of numbers only once (per draw of course).
Exercise random-4: Game logic for Hangman
Your friend designed a Hangman game that looks like the following:
Your friend has programmed the user interface and also a skeleton for the game logic. Now, she asks you to finish the remaining pieces of the game logic.
Amongst other stuff, with TMC you get the following skeleton for the class
HangmanLogic
public class HangmanLogic { private String word; private String guessedLetters; private int numberOfFaults; public HangmanLogic(String word) { this.word = word.toUpperCase(); this.guessedLetters = ""; this.numberOfFaults = 0; } public int numberOfFaults() { return this.numberOfFaults; } public String guessedLetters() { return this.guessedLetters; } public int losingFaultAmount() { return 12; } public void guessLetter(String letter) { // program here the functionality for making a guess // if the letter has already been guessed, nothing happens // it the word does not contains the guessed letter, the number of faults increases // the letter is added among the already guessed letters } public String hiddenWord() { // program here the functionality for building the hidden word // create the hidden word by iterating through this.word letter by letter // if the letter in turn is within the guessed words, put it in the hidden word // if the letter is not among the guessed ones, replace it with _ in the hidden word // return the hidden word at the end return ""; } }
In this assignment, you should only touch class
HangmanLogic
and implement the functionality of the methodsguessLetter(String letter)
andhiddenWord()
.Testing the code
The TMC project includes two classes that help you with testing. The class Main starts the graphical version of the game. The class TestProgram can be used to test the class HangmanLogic.
Exercise random-4.1: Guessing a letter
Touch only the method
guessLetter(String letter)
in this assignment!When a user guesses a letter, the user interface calls method
guessLetter
which is supposed to take care of action related to guessing a letter. First, it should check if the letter has already been guessed. In that case, the method does not do anything.The method increases the number of faults (
this.numberOfFaults
) if the word (this.word
) does not contain the guessed letter. Then the letter is added among the already guessed letters (the object variablethis.guessedLetters
).An example of how the method
guessLetter
should work:HangmanLogic l = new HangmanLogic("kissa"); System.out.println("guessing: A, D, S, F, D"); l.guessLetter("A"); // correct l.guessLetter("D"); // wrong l.guessLetter("S"); // correct l.guessLetter("F"); // wrong l.guessLetter("D"); // This should not have any effect on the number of faults since D was already guessed System.out.println("guessed letters: "+l.guessedLetters()); System.out.println("number of faults: "+l.numberOfFaults());
guessing: A, D, S, F, D guessed letters: ADSF number of faults: 2
Exercise random-4.2: Creating the hidden word
The Hangman user interface shows a hidden version of the word to the user. In the above figure, the hidden word is METO_I. All the letters that the user has already guessed are shown in the hidden word but the rest of the letters are replaced with underscores. In this part of the assignment, you should complete the method
hiddenWord
of Hangman logic that takes care of building the hidden word for the user interface.Commands
while
,charAt
andcontains
might be useful here. Note that a single char can be made into a string as follows:char c = 'a'; String aString = "" + c; An example of how the method works: HangmanLogic l = new HangmanLogic("kissa"); System.out.println("word is: "+l.hiddenWord()); System.out.println("guessing: A, D, S, F, D"); l.guessLetter("A"); l.guessLetter("D"); l.guessLetter("S"); l.guessLetter("F"); l.guessLetter("D"); System.out.println("guessed letters: "+l.guessedLetters()); System.out.println("number of faults: "+l.numberOfFaults()); System.out.println("word now: "+l.hiddenWord());
word is: _____ guessing: A, D, S, F, D guessed letters: ADSF number of faults: 2 word now: __SSA
Now, you can test the game by using class Main. You can change the guessed word by changing the constructor parameter of the game logic:
HangmanLogic logic = new HangmanLogic("parameter"); HangmanUI game = new HangmanUI(logic); game.start();
The game is played with the keyboard. You can end the game by pressing x in the upper left corner of the game window.