Tim
Tim

Reputation: 375

Return a random line from a text file

I want to make a Mad Libs program where you write a mad libs template and the computer fills in the blanks for you. I've got this so far:

package madlibs;
import java.io.*;
import java.util.Scanner;

/**
 *
 * @author Tim
 */
public class Madlibs {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws IOException {
    File nouns = new File("nounList.txt");
    Scanner scan = new Scanner(nouns);
    while(scan.hasNextLine()){
        if("__(N)".equals(scan.nextLine().trim())){
            int word = (int) (Math.random() * 100);

        }
    }
}

}

The nounList.txt file contains a list of nouns, each on a separate line. Question is: How do I use the Math.random function to then choose which line is used?

Upvotes: 2

Views: 2140

Answers (3)

Rainbolt
Rainbolt

Reputation: 3660

There are two major tasks:

Read all of the nouns

    // Open the file
    File file = new File("MyFile.txt");

    // Attach a scanner to the file
    Scanner fin = new Scanner(file);

    // Read the nouns from the file
    ArrayList<String> nouns = new ArrayList<>();
    while (fin.hasNext()) {
        nouns.add(fin.next());
    }

Pick one at random

    // Pick one at random
    int randomIndex = (int)(Math.random() * nouns.size());
    String randomNoun = nouns.get(randomIndex);

    // Output the result
    System.out.println(randomNoun);

For example, if we have 10 nouns, then Math.random() * 10 yields a range from 0.0 to 9.999...9. Casting to int truncates the decimal, leaving an equal distribution between 0 through 9.

Note that you could technically roll a perfect 10.0, and the program would crash with an IndexOutOfBoundsException. It's statistically impossible for this to happen, but as we all know, statistically impossible isn't really good enough in code. Consider adding logic to handle the case where you roll 10.0.

Upvotes: 0

Marcelo Tataje
Marcelo Tataje

Reputation: 3871

I would make another approach as suggested by one of the comments I saw:

try {
        //I would prefer to read my file using NIO, which is faster
        Path pathToMyTextFile = Paths.get("nounList.txt");
        //Then I would like to obtain the lines in Array, also I could have them available for process later
        List<String> linesInFile = Files.readAllLines(pathToMyTextFile, StandardCharsets.ISO_8859_1);
        //If I want to access a random element, I would use random methods to access a random index of the list and retrieve that element
        Random randomUtil = new Random();

        //I will use the formula for random and define the maximum (which will be the length of the array -1) and the minimum which will be zero
        //since the indexes are represented from 0 to length - 1
        int max = linesInFile.size() - 1;
        int min = 0;

        //You can simplify this formula later, I'm just putting the whole thing
        int randomIndexForWord = randomUtil.nextInt((max - min + 1)) + min;

        //Here I get a random Noun
        String randomWord = linesInFile.get(randomIndexForWord);

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

That would be another way to do it, without the need of accessing this each time you require a noun.

Regards and... happy coding :)

Upvotes: 0

MCMastery
MCMastery

Reputation: 3249

Get all the nouns in a list, and then choose a random element out of the list.

Example:

// Nouns would contain the list of nouns from the txt file
List<String> nouns = new ArrayList<>();
Random r = new Random();
String randomNoun = nouns.get(r.nextInt(0, nouns.length));

Upvotes: 1

Related Questions