Cumulative Project 4 | Game Logic Pt. II

Hey All,

I’ve searched on these forums, and others, to no avail. I need your help. I am at the end of the lesson, Step 21:

"Try it out!

If you’ve completed every step, Unquote is now… partially functional!

Tab over to Main.java to “play” the game:

  1. Start the game by invoking MainActivity.startNewGame();
  2. Retrieve the current Question by calling MainActivity.getCurrentQuestion();
  3. Print the Question and answers using the provided printQuestion() method
  4. Set an answer directly on the Question by modifying the playerAnswer member variable
  5. Then submit an answer by invoking MainActivity.onAnswerSubmission();
  6. Go nuts!"

From what I have seen online, the code should work at this point and print the question, at least. But, my code isn’t doing even that. Without doing the steps 4-6, I am getting this error:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out-of-bounds for length 0 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248) at java.base/java.util.Objects.checkIndex(Objects.java:372) at java.base/java.util.ArrayList.get(ArrayList.java:440) at MainActivity.chooseNewQuestion(MainActivity.java:33) at MainActivity.startNewGame(MainActivity.java:24) at Main.main(Main.java:4)

Lesson Link

Here’s my Code Currently:

Question.java :

public class Question {
    int imageId;
    String questionText;
    String answer0;
    String answer1;
    String answer2;
    String answer3;
    int correctAnswer;
    int playerAnswer = 1;

    public Question(int imageIdentifier,
      String questionString,
      String answerZero,
      String answerOne,
      String answerTwo,
      String answerThree,
      int correctAnswerIndex) {
        imageId = imageIdentifier;
        questionText = questionString;
        answer0 = answerZero;
        answer1 = answerOne;
        answer2 = answerTwo;
        answer3 = answerThree;
        correctAnswer = correctAnswerIndex;
        playerAnswer = 1;
        
    }

    boolean isCorrect() {
      return correctAnswer == playerAnswer;
    }
}

And my MainActivity.java :

import java.util.ArrayList;

public class MainActivity {

    // TODO #1: add integer member variables here
    int currentQuestionIndex;
    int totalCorrect;
    int totalQuestions;

    // TODO #2: add ArrayList member variable here
    ArrayList<Question> questions = new ArrayList<Question>();

    // TODO #3 add startNewGame() here    
    void startNewGame() {
      Question question1 = new Question(921238, "How tall is the Eiffel tower?", "1024 ft", "1063 ft", "1124 ft", "1163 ft", 1);
      Question question2 = new Question(107343, "Who invented the computer algorithm?", "Charles Babbage", "John Carmack", "Alan Turing", "Ada Lovelace", 3);
      Question question3 = new Question(748294, "What is the name for the patch of skin found on your elbow?", "Elbow Skin", "Fascia Elbora", "Wenis", "Todd", 2);
      ArrayList<Question> questions = new ArrayList<Question>();
      questions.add(question1);
      questions.add(question2);
      questions.add(question3);
      totalCorrect = 0;
      totalQuestions = questions.size();
      Question firstQuestion = chooseNewQuestion();
      // displayQuestion(firstQuestion);
      // displayQuestionsRemaining(questions.size());
    }

    // TODO #4 add chooseNewQuestion() here
    Question chooseNewQuestion() {
      int randomNum = generateRandomNumber(2);
      currentQuestionIndex = randomNum;
      return questions.get(currentQuestionIndex);
    }

    // TODO #5 add getCurrentQuestion() here
    Question getCurrentQuestion() {
      return questions.get(currentQuestionIndex);
    }

    // TODO #6 add onAnswerSubmission() here
    void onAnswerSubmission() {
      Question currentQuest = getCurrentQuestion();
      if (currentQuest.isCorrect()) {
        totalCorrect =+ 1;
        questions.remove(currentQuest);
      }
      //displayQuestionsRemaining(questions.size());
      if(questions.size() == 0) {
        System.out.println("Game Over");
        startNewGame();
        chooseNewQuestion();
        // TODO: uncomment after implementing displayQuestion()
        // displayQuestion(getCurrentQuestion());
      }
    }
    

    int generateRandomNumber(int max) {
      double randomNumber = Math.random();
      double result = max * randomNumber;
      return (int) result;
    }

    String getGameOverMessage(int totalCorrect, int totalQuestions) {
        if (totalCorrect == totalQuestions) {
            return "You got all " + totalQuestions + " right! You won!";
        } else {
            return "You got " + totalCorrect + " right out of " + totalQuestions + ". Better luck next time!";
        }
    }

    public static void main(String[] args) {
      System.out.println("Test: Working");
    }
}

And, lastly, my Main.java :

public class Main {
    public static void main(String[] args) {
        MainActivity newMainActivity = new MainActivity();
        newMainActivity.startNewGame();
        System.out.println("Questions remaining: " + newMainActivity.totalQuestions);
        Question currentQuestion = newMainActivity.getCurrentQuestion();
        printQuestion(currentQuestion);
        // Play the game!
        
        
    }

    static void printQuestion(Question question) {
        System.out.println("Question: " + question.questionText);
        System.out.println("Option 1: " + question.answer0);
        System.out.println("Option 2: " + question.answer1);
        System.out.println("Option 3: " + question.answer2);
        System.out.println("Option 4: " + question.answer3);
    }
}

From what I can tell, the error is pointing out a mismatch in the ArrayList.size() and some method’s calling the wrong index location. That, or one that doesn’t exist? However, when I looked through the code it points to, it matches what others have used and have working on theirs they posted here.

This lesson has been great for the most part. However, when it suddenly goes from individual components, like learning loops or arrays, to something like this, putting it all together, and having it span across multiple .java files or classes, it gets very confusing and difficult to debug. I think this lesson and cumulative ones like it, need a lot more support and explanations. These forums are also no help directly, because there are too many potential issues, for me to find the exact one causing my error message. This course isn’t free. I would prefer not to have to wait a week for an answer, while paying to use Pro.

What Am I Missing? Please Help!

1 Like

Take a look at your code in MainActivity.java. You’re initializing the questions twice, once in the class scope and once in the scope of the method startNewGame(). chooseNewQuestion() will use the class-scoped variable when calling return questions.get(currentQuestionIndex);, as the questions variable declared inside startNewGame() only exists inside said method. How can you fix this?

Answer: Remove the line declaring and assigning a value to the questions variable inside the startNewGame() method. Keep the one that is class-scoped.

1 Like

Thank you SO much!

This is a bug in the tutorial instructions. Step 5.

And array we go.

In startNewGame() , create a new ArrayList and assign it to the questions member variable you defined in task 2. Then, add all of your Question objects to the ArrayList .

You can then see in the hint, the example they give:

Hint

To create a new ArrayList , we use the following syntax, Arraylist<Homework> myHomework = new ArrayList<>; .

The ArrayList object provides the add(<T> element) method, which allows us to add a new object of type <T> to the end of the ArrayList , like so, myHomework.add(mathProblems);

Question I have now, is: What did they want me to put there instead if just removing that step all together (parts in bold) fixes my code?

I reported the bug on the lesson page from the link in the lesson.

Does your code work now? If so could you post the full code to MainActivity? I’m so stuck I don’t know where to begin and there doesn’t seem to be any “bug-free” solutions on this forum. My error is saying:

“Error: Main method not found in class MainActivity, please define the main method as: public static void main(String args) or a JavaFX application class must extend javafx.application.Application”

but comparing my code to other examples, I can’t see what I’ve done differently. I definitely agree with you that it’s very frustrating that there is no solution anywhere for when you get really stuck in cumulative projects.

1 Like

Yes, it works now. See solution above. See my code above. To get mine to work, I had remove ArrayList<Question> questions = new ArrayList<Question>(); from the 4th line within the method startNewGame() within MainActivity.java.

This was added because of the instructions in Step 5. It didn’t make sense to me to add it at the time, but I assumed I just didn’t know any better. Hopefully they fix that, seems many are having this issue.

2 Likes

Thanks - just wanted to make sure there weren’t any changes needed. This helps a lot, I felt like I was going round in circles!

Would you mind sharing the code you used to play the game? I’m sure I’m following the instructions in no. 21, but nothing is showing up, and I can’t find anything on the forum. honestly, I’m really sick of this task and want to move on!

I get it. I had to look this up too.

Step 21

The 1-3 are already done for you.

  1. Start the game by invoking MainActivity.startNewGame();
  2. Retrieve the current Question by calling MainActivity.getCurrentQuestion();
  3. Print the Question and answers using the provided printQuestion() method`

So…

  1. Set an answer directly on the Question by modifying the playerAnswer member variable

In Main.java, in the main method, the Question class (first tab) has already been passed into this method as currentQuestion. See it above a few lines? Question currentQuestion = new Question();

You need to use that in a similar pattern as they used mainActivity.startNewGame();

ie. currentClass.whatYouWantToChangeInSaidClass = newIntValueYouChoose;
eg. currentQuestion.variable = 1;

Then, to see if it worked, have the machine print it. Aka, put the same currentQuestion.whatYouWantToChangeInSaidClass inside the parenthesis of System.out.println(); on a new line. That’ll print the newIntValueYou...Chose.

ie. System.out.println(currentClass.whatYouWantToChangeInSaidClass);
eg. System.out.println(currentQuestion.variable);

  1. Then submit an answer by invoking MainActivity.onAnswerSubmission();

Do the same pattern as before.
ie.
classAsItWasPassedIntoThisMethod.methodInThatClass();
System.out.println(classAsItWasPassedIntoThisMethod.methodInThatClass);

  1. Go nuts!

I didn’t do this part. I was so happy to have the answer and just be done. So, I moved on.

1 Like

Oh my god, I think you may have just saved my laptop from being thrown out the window, thank you!!!

I also definitely wouldn’t have remembered I needed to call onAnswerSubmission ::woman_facepalming: … just as a sanity check, my version of the game doesn’t allow you to “play” it properly in that it adds up the answers and gives you a game over etc, it’s just doing one question at a time manually. I didn’t miss a massive step did I?

That’s what mine does too.

Thank God for that. Never been more happy to move on! Appreciate your help

Thanks for this post! I am really trying to understand this exercises, it’s supposed to be beginner’s friendly!

1 Like

Haha, right? How is introducing new techniques during a cumulative project without explaining it, beginner friendly? Just wait, it keeps happening.

At least for me, I began later than you, than I am learning a lot through yours posts and the others! Thanks anyway!