Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java

Hariidaran Tamilmaran
seal-mask
.a{fill-rule:evenodd;}techdegree
Hariidaran Tamilmaran
iOS Development Techdegree Student 19,305 Points

Problem with the first project in the Android Techdegree

All of this was done with IntelliJ IDEA.

Here are the errors:

Exception in thread "main" java.lang.NullPointerException
    at com.hariidaran.model.Imxporter.exportTo(Imxporter.java:47)
You took 3 tries to guess that there are 3 bananas in the jar, but you could've done better. Try again. at com.hariidaran.Game.main(Game.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

I don't understand how it's wrong, even though I find nothing wrong at line 47 in Imxporter.java, but here's my code:

(Code for download at my GitHub repository)

Game.java
package com.hariidaran;

import com.hariidaran.model.Imxporter;
import com.hariidaran.model.Jar;
import com.hariidaran.model.Prompter;

public class Game {

    public static void main(String[] args) {
        Jar jar = new Jar();
        Prompter prompter = new Prompter(jar);
        Imxporter imxporter = new Imxporter(prompter);

        imxporter.importFrom("scores.txt");
        prompter.play();
        imxporter.exportTo("scores.txt");
    }
}
Jar.java
package com.hariidaran.model;

import java.util.Random;

public class Jar {
    private String mItemName;
    private Random mGenerator;
    private int mItems;
    private int mMaxItems;

    public Jar() {
        mGenerator = new Random();
    }

    // -HELPER-METHODS--------------------------------------------

    public String getItemName() {
        return mItemName;
    }

    public void setItemName(String itemName) {
        mItemName = itemName;
    }

    public int getItems() {
        return mItems;
    }

    public int getMaxItems() {
        return mMaxItems;
    }

    public void setMaxItems(int maxItems) {
        mMaxItems = maxItems;
    }

    // -MAIN-METHODS----------------------------------------------

    public void fill() {
        mItems = mGenerator.nextInt(mMaxItems) + 1;
    }

    public boolean isEmpty() {
        return mItems == 0;
    }
}
Prompter.java
package com.hariidaran.model;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Prompter {
    private Jar mJar;

    private BufferedReader mReader;

    private String mName;
    private int mNumberOfGuesses = 0;
    private String mFinalStatement;

    public Prompter(Jar jar) {
        mJar = jar;
        mReader = new BufferedReader(new InputStreamReader(System.in));
    }

    // -HELPER-METHODS--------------------------------------------

    // Checks if a string is a number
    private static boolean isNaN(String string) {
        try {
            float number = Float.parseFloat(string);
        } catch (NumberFormatException nfe) {
            return true;
        }

        return false;
    }

    // Prints out the string (title) in a specific way
    private void printTitle(String title) {
        System.out.printf("%n%s%n", title.toUpperCase());
        System.out.printf("========================%n%n");
    }

    // Explains the game
    private void explainGame() {
        System.out.printf("%n" +
                "This is a game where you have to guess the" +
                "%n" +
                "number of items in a jar (which you can't see)." +
                "%n%n" +
                "As you are the admin of this game, you can" +
                "%n" +
                "enter what the items in the jar are to be" +
                "%n" +
                "called. You can also enter the maximum number" +
                "%n" +
                "of items." +
                "%n%n");
    }

    // Prompt for guess
    private void promptForGuess() throws IOException {
        System.out.printf("%nYour goal is to guess how many %ss are there in there " +
                        "(and it can hold from 1 to %d %ss).",
                mJar.getItemName(), mJar.getMaxItems(), mJar.getItemName());

        // Asks you to start the game
        System.out.printf("%n%nReady? (press ENTER or RETURN to play)");
        mReader.readLine();

        // Start guessing
        String guess = "";

        List<String> guesses = new ArrayList<>();

        // While your guess isn't the answer, guess again
        while (!guess.equals(mJar.getItems() + "")) {
            System.out.printf("%nGuess: ");
            guess = mReader.readLine();

            // Send out warning if 1 or 0, special characters and letters are entered
            if (isNaN(guess) || (Integer.parseInt(guess) == 0 && Integer.parseInt(guess) == 1)) {
                System.out.println("No special characters or letters or 0 allowed. Try again.");
            } else if (guesses.contains(guess)) {
                System.out.println("Number already guessed before.");
            } else {
                // The guess counter gets incremHented
                guesses.add(guess);
                mNumberOfGuesses++;
            }
        }
    }

    private void showStatement() {
        // Expectation to match
        boolean isMatchedExpectation = mNumberOfGuesses < Math.round(mJar.getMaxItems() / 2);

        // If the player matches the expectation
        if (isMatchedExpectation) {
            // If the player took 1 try to guess the answer
            if (mNumberOfGuesses == 1) {
                mFinalStatement = String.format("%nYou took 1 try to guess that there is ");
            }
            // If the player took more than 1 try to guess the answer
            else {
                mFinalStatement = String.format("%nYou took %d tries to guess that there are ", mNumberOfGuesses);
            }

            // If there is only one
            if (mJar.getItems() == 1) {
                mFinalStatement += "1 " + mJar.getItemName() + " in the jar,";
            } else {
                mFinalStatement += mJar.getItems() + " " + mJar.getItemName() + "s in the jar,";
            }

            mFinalStatement += " and it's like you knew the answer! Good job!";

            System.out.print(mFinalStatement);
        } else {
            System.out.printf("%nYou took %d tries to guess that there are %d %ss in the jar," +
                            " but you could've done better. Try again.",
                    mNumberOfGuesses, mJar.getItems(), mJar.getItemName());
        }
    }

    public ArrayList<String> getResults() {
        String name = mName;
        String itemsPresent = mJar.getItems() + " " + mJar.getItemName();
        String maxItems = mJar.getMaxItems() + " " + mJar.getItemName();
        String numberOfGuesses = mNumberOfGuesses + "";

        String[] results = {name, itemsPresent, maxItems, numberOfGuesses};

        return new ArrayList<>(Arrays.asList(results));
    }

    // Prints out an error
    public void printError(Exception e) {
        System.out.printf("%n%nOops! Something went wrong in the program.%n" +
                          "Try running the program again.%n%n");
        e.printStackTrace();
    }

    // -MAIN-METHODS----------------------------------------------

    // Play the program
    public void play() {

        explainGame();

        try {
            startAdminSetup();
            startGame();
        } catch (IOException ioe) {
            printError(ioe);
        }
    }

    // Administrator Setup
    private void startAdminSetup() throws IOException {
        // Prints out "ADMINISTRATIVE SETUP"
        printTitle("Administrator Setup");

        // Asks for the player's name
        System.out.print("Name of the player:  ");
        mName = mReader.readLine();

        // Asks the player what to call the items
        System.out.print("Name of item (it should be singular):  ");
        String itemName = mReader.readLine();
        if (!(itemName.equals("") || itemName.equals(String.format("%n"))) || isNaN(itemName)) {
            mJar.setItemName(itemName);
        } else {
            mJar.setItemName("item");
        }

        String maxItemsString = "";
        int maxItems = 0;

        // Expectation to match
        boolean isNotMatched = isNaN(maxItemsString) ||
                maxItems == 0 ||
                maxItems == 1 ||
                maxItemsString.equals(String.format("%n")) ||
                maxItemsString.equals("f");

        // Loops till maxItemsString is a number
        while (isNotMatched) {
            System.out.printf("Maximum number of %ss in the jar:  ", mJar.getItemName());
            maxItemsString = mReader.readLine().trim().toLowerCase();

            // Send out warning if 1 or 0, special characters and letters are entered
            try {
                maxItems = Integer.parseInt(maxItemsString);
            } catch (NumberFormatException nfe) {
                System.out.println("1 or 0, and special characters, letters are not allowed.");
            }

            isNotMatched = isNaN(maxItemsString) ||
                    maxItems == 0 ||
                    maxItems == 1 ||
                    maxItemsString.equals(String.format("%n")) ||
                    maxItemsString.equals("") ||
                    maxItemsString.equals("f");
        }

        // The maximum number of items it can hold is assigned
        mJar.setMaxItems(maxItems);
    }

    // Start the game
    private void startGame() throws IOException {
        mJar.fill();

        // Prompt for guess
        promptForGuess();

        // Shows the score
        showStatement();
    }
}
Imxporter.java
package com.hariidaran.model;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Imxporter {
    private Prompter mPrompter;
    private List<List<String>> mScores;

    public Imxporter(Prompter prompter) {
        mPrompter = prompter;
    }

    public void importFrom(String fileName) {
        try (
                FileInputStream fis = new FileInputStream(fileName);
                BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
        ) {
            String line;

            while ((line = reader.readLine()) != null) {
                String[] args = line.split("\\|");
                List<String> score = new ArrayList<>(Arrays.asList(new String[] {
                        args[0], args[1], args[2], args[3]
                }));

                mScores.add(score);

                System.out.printf("%s found out there were %s in a jar " +
                                "which could hold %s, in %s tries.%n",
                        args[0], args[1], args[2], args[3]);
            }
        } catch (IOException ioe) {
            mPrompter.printError(ioe);
        }
    }

    public void exportTo(String fileName) {
        try (
                FileOutputStream fos = new FileOutputStream(fileName);
                PrintWriter writer = new PrintWriter(fos);
        ) {
            List<String> score = mPrompter.getResults();

            mScores.add(score);

            for (List<String> args : mScores) {
                writer.printf("%s|%s|%s|%s",
                args.get(0), args.get(1), args.get(2), args.get(3));
            }

            System.out.printf("%n%nSaving scores...");
        } catch (IOException ioe) {
            mPrompter.printError(ioe);
        }
    }
}

1 Answer

Kourosh Raeen
Kourosh Raeen
23,733 Points

In the Imxporter class you've declared mScores but it doesn't look like you've initialized the list anywhere, so mScores is null and calling the add method on it will throw the exception.

Kourosh Raeen
Kourosh Raeen
23,733 Points

Glad I could help! How are you liking the Techdegree?

Hariidaran Tamilmaran
seal-mask
.a{fill-rule:evenodd;}techdegree
Hariidaran Tamilmaran
iOS Development Techdegree Student 19,305 Points

So far so good. They make you code projects on your own, which is really helpful because in the courses, we learn as we make something. But there is a path for you to learn from beginner to expert, which is really helpful for me.