-2

While I transformed parts of my code into methods, an integer I mean to increase under a certain condition (the player score) doesn't. This is a series of methods inside other methods inside a single method that gets run in main, where everything but the integer increase works fine and it's really bugging me out.

I ended up with creating a public static int method for the point increase that gets called inside a public static void method that's basically an if function. If the player's answer was the correct answer, print out a "Correct!" message and call the player score increase method. This is where I left it at before caving in and creating a stack overflow account. Here's the full code

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        /*Questions*/
        String[] questions = new String[5];
        questions[0] = "What year did the hit cartoon show Tom & Jerry debut in for the first time?";
        questions[1] = "In the famous japanese franchise Dragon Ball Z, most main characters can undergo what powerful transformation?";
        questions[2] = "The famous video game character, Sonic, is of what animal species?";
        questions[3] = "Java, the programming language, was created by whom?";
        questions[4] = "The famous social platform, Roblox, launched for the first time in what year?";
        /*Answers*/
        String[] answers = new String[5];
        answers[0] = "1941";
        answers[1] = "super saiyan";
        answers[2] = "hedgehog";
        answers[3] = "james gosling";
        answers[4] = "2006";

        Scanner playerInput = new Scanner(System.in);

        int playerScore = 0;

        /*Trivia Start*/
        System.out.println("Welcome to Jpeg Louie's Trivia v3 (now with methods!)");
        System.out.println("You'll be expected to type the correct answer. Mind your whitespaces and punctuations");
        System.out.println(" ");

        while(true){
            doTriviaQuiz(questions, answers, playerInput, playerScore);

            /*Trivia End*/
            System.out.println("----------------------------------------------------------");
            System.out.println("The trivia is over! Thanks for playing :)");
            System.out.println("CALCULATING SCORE");
            System.out.println("...");
            System.out.println("...");
            System.out.println("...");
            System.out.println("Your score was: " + playerScore + " correct questions out of " + questions.length);

            /*Special Score Message*/
            if(playerScore == 0){
                System.out.println("Looks like you got all questions wrong...");
                System.out.println("Try to get them all correct, I might reward you with something ;)");
            } else if(playerScore == questions.length){
                System.out.println("Congratulations! You beat the trivia quiz!");
                System.out.println("Here's a list of commands that trigger special events");
                System.out.println("(When prompted to play again, type the desired command to execute it)");
            }

            /*Play Again?*/
            System.out.println(" ");
            System.out.println("Play again? Type [Y] for Yes and anything else for No");
            String playAgain = playerInput.nextLine();

            if(playAgain.equalsIgnoreCase("y")){
                System.out.println(" ");
            } else {
                break;
            }
        }
    }
    public static void doTriviaQuiz(String[] questions, String[] answers, Scanner playerInput, int playerScore) {
        doQuestionsXTimes(questions, answers, playerInput, playerScore);
    }

    public static void doQuestionsXTimes(String[] questions, String[] answers, Scanner playerInput, int playerScore) {
        for(int i = 0; i < questions.length; i++) {
            doQuestion(questions, answers, playerInput, playerScore, i);
        }
    }

    public static void doQuestion(String[] questions, String[] answers, Scanner playerInput, int playerScore, int i) {
        System.out.println("Question " + (i + 1) + ": " + questions[i]);
        String answer = playerInput.nextLine();

        checkCorrectAnswer(answers, i, answer, playerScore);
    }

    public static void checkCorrectAnswer(String[] answers, int i, String answer, int playerScore) {
        if (answer.equalsIgnoreCase(answers[i])) {
            System.out.println("Correct!");
            playerScore = incrementPlayerScore(playerScore);
        } else {
            System.out.println("Incorrect! The answer was: " + answers[i]);
        }
    }

    public static int incrementPlayerScore(int playerScore){
        playerScore++;
        return playerScore;
    }
}```
  • This code does not work because you are hoping that code like `playerScore = ...` will change **the caller's** `playerScore` variable, simply because it was *passed as a parameter*. This is called *pass by reference*, and it does not work that way in Java. – Karl Knechtel May 26 '23 at 04:52
  • @KarlKnechtel, unless it's an array. – Reilas May 26 '23 at 04:54
  • 1
    @Reilas reassigning the array entirely will show the same behaviour as here. *Modifying* the array by assigning *to an index* will of course reflect the change. This is explained in the linked duplicate, which is quite comprehensive as this is an extremely common problem/topic. – Karl Knechtel May 26 '23 at 04:58
  • @KarlKnechtel, that's why I mentioned it. – Reilas May 26 '23 at 05:09
  • @KarlKnechtel, pass-by-reference and pass-by-value are not opposing. They just share the same _"pass-by-"_ prefix. – Reilas May 26 '23 at 05:11
  • @jpeg_louie You can get the incremented `playerScore` value to the main method by returning the `playerScore` from each method of the method chain. If you could change the return type of each method from `void` to `int` and return the `playerScore`, and assign the return value of `doTriviaQuiz` method to `playerScore` variable itself. – chameerar May 26 '23 at 05:17

1 Answers1

0

You never change the value of player score.

Your incrementPlayerScore method in fact increase the data passed by parameter, but you call that method into checkCorrectAnswer and there you never return the new playerScore data to change the actual

public static void checkCorrectAnswer(String[] answers, int i, String answer, int playerScore) {
    if (answer.equalsIgnoreCase(answers[i])) {
        System.out.println("Correct!");
        playerScore = incrementPlayerScore(playerScore);
    } else {
        System.out.println("Incorrect! The answer was: " + answers[i]);
    }
}

If you want to still have the same structure, you must change the method return type of your methods. So that you return the score incremented, and you can save it in your local variable.

This way could work for you:

first change the increment and checkAnswer methods to return the new score:

    public static int checkCorrectAnswer(String[] answers, int i, String answer, int playerScore) {
    if (answer.equalsIgnoreCase(answers[i])) {
        System.out.println("Correct!");
        playerScore = incrementPlayerScore(playerScore);
        return playerScore;
    }
        System.out.println("Incorrect! The answer was: " + answers[i]);
        return playerScore;
}

public static int incrementPlayerScore(int playerScore){
    playerScore++;
    return playerScore;
}

Then just return the answer of each question, so you can check if it was correct but saving the score this way:

    public static int doQuestionsXTimes(String[] questions, String[] answers, Scanner playerInput, int playerScore) {
    String ans;
    for(int i = 0; i < questions.length; i++) {
        ans=doQuestion(questions, answers, playerInput, playerScore, i);
        playerScore = checkCorrectAnswer(answers, i, ans, playerScore);
    }
    return playerScore;
}

public static String doQuestion(String[] questions, String[] answers, Scanner playerInput, int playerScore, int i) {
    System.out.println("Question " + (i + 1) + ": " + questions[i]);
    String answer = playerInput.nextLine();
    return answer;
    //checkCorrectAnswer(answers, i, answer, playerScore);
}

finally, you just have to return the playerScore in the method where you call everything and save it in the variable you're going to compare.

public static int doTriviaQuiz(String[] questions, String[] answers, Scanner playerInput, int playerScore) {
    playerScore = doQuestionsXTimes(questions, answers, playerInput, playerScore);
    return playerScore;
}



playerScore = doTriviaQuiz(questions, answers, playerInput, playerScore);

This might not be the best way to approach the exercise, but could work fine for you without change very much the structure of your code.

Santiago
  • 1
  • 1