5
\$\begingroup\$

I'm pretty new to Java and I made a quick and simple math equation game. Feel free to give me tips on the way I write code and how I can make it smaller, more efficient, or better-looking!

import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;

public class Addition {
    public static Scanner input = new Scanner(System.in);
    public static int Answer;

    public static int Random1, Random2, Random3;
    public static int sum;

    public static int win, loss;
    public static int Score, TotalScore;
    public static long AnswerTime;
    public static double TotalTime;

    public static void main(String[] args) {

        AddGame();

    }

    public static void AddGame() {

        RandomEasy(); // This can be changed to (RandomMed() or RandomHard())

        // Tell the user to solve the equation given to them
        // Generate the time(Seconds) it took for the user to answer

        long startTime = System.currentTimeMillis();
        while (true) {

            String line = input.nextLine();
            // Check if the user's input is and number. If not, retry!
            try {
                Answer = Integer.parseInt(line);
                break;
            } catch (NumberFormatException e) {
                System.out.print("Please enter a number : ");
            }
        }
        long stopTime = System.currentTimeMillis();

        AnswerTime = (stopTime - startTime) / 1000; // Change user's input time to (seconds)

        TotalTime += AnswerTime; // Get the Total time(seconds) of the 20 inputs

        // Loop until 10 equations have been set.

        if ((win + loss) != 9) {
            if (Answer == sum) {
                win++;
                System.out.println("Correct!");
                AddGame();

            } else if (Answer != sum) {
                loss++;
                System.out.println("Wrong!");
                AddGame();

            }
        } else if ((win + loss) == 9) {
            double Percentage = win/10.0;
            System.out.println();
            System.out.println("Your score is : " + win + "/10(" + Percentage *100 + "%)");
            System.out.println("Your average seconds/answer is : " + TotalTime/10 +  " seconds");
            System.out.println();
            System.out.print("Would you like to retry? (Y or N) : ");
            while (true) {
                String retry = input.nextLine();
                // If "y" or "Y", restart the game
                if (("y".equals(retry)) || ("Y".equals(retry))) {
                    win = 0;
                    loss = 0;

                    AddGame();


                    // If "n" or "N", exit the game
                } else if (("n".equals(retry)) || ("N".equals(retry))) {
                    System.out.println("Thank you for Playing!");
                    System.exit(1);

                    // If the user enters an invalid input, this will ask them to try again
                } else if (!("y".equals(retry))
                        || !("Y".equals(retry) || ("n".equals(retry)) || !("N".equals(retry)))) {
                    System.out.print("Invalid input. Would you like to retry?(Y or N) : ");

                }
            }
        }
    }

    public static void RandomEasy(){
        //(1-10)
        Random1 = (int) (Math.random() * 10 + 1);
        Random2 = (int) (Math.random() * 10 + 1);
        // Add both numbers together to make a 'sum'
        sum = Random1 + Random2;
        System.out.print("What is " + Random1 + " + " + Random2 + "? : ");

    }
    public static void RandomMed(){
        //(15-30)
        Random1 = ThreadLocalRandom.current().nextInt(15, 30 + 1);
        Random2 = ThreadLocalRandom.current().nextInt(15, 30 + 1);
        // Add both numbers together to make a 'sum'
        sum = Random1 + Random2;
        System.out.print("What is " + Random1 + " + " + Random2 + "? : ");

    }

    public static void RandomHard(){
        //(30-45)
        Random1 = ThreadLocalRandom.current().nextInt(30, 45 + 1);
        Random2 = ThreadLocalRandom.current().nextInt(30, 45 + 1);
        Random3 = ThreadLocalRandom.current().nextInt(30, 45 + 1);
        // Add the 3 random numbers together to make a 'sum'
        sum = Random1 + Random2 + Random3;
        System.out.print("What is " + Random1 + " + " + Random2 + " + " + Random3 + "? : ");


    }

}

Quick game introduction:

  • The game generates 10 easy equations.
  • It will check how long the user took to answer the equations (in seconds)
  • When the 10 equations are answered, it will give the user his grade (example: 2/5(40.0%))
  • The game will now tell the user their average seconds per answer.
  • I added medium and hard difficulty!
\$\endgroup\$
2
\$\begingroup\$

That's a really interesting problem. My first criticism is that you are not layering your program. There's one class that handles everything. From user input, generating questions, verifying the users answers, to managing game state.

The code is also not easily extensible. What if you wanted to add multiplication questions? Or language questions? Or geographic quiz? Ideally your code should be easily modifiable to handle these different questions. Right now it's tightly bound to showing math questions - and only one type at that - addition.

Take a look at the code I wrote below. It's a draft of something that would let you easily change the type of questions being shown to the user. You would have to create an interface/class of type QuestionGenerator which would have just one method, generate(). That method would simply return a Question type object. As far as your code is concerned, it doesn't have to know anything about the nature of the question. All it has to know is whether the user answered the question correctly.

The Question class would have just one method, validateAnswer(). Notice that we are not specifying anything about user input - maybe the response comes from a website, maybe command line, maybe over the network. Your program can handle changing that easily. It's all behind an abstract interface. You can easily make your game run over the network, from a graphical user interface. Anything. Hell you can make it run from a microwave control board as long as you create Java adapter for that. Possibilities are endless.

If you think about it, your main class should only care about running the actual game. So all it takes care of is checking whether the game should still be running, generating questions and keeping score. Everything else is delegated to classes that do the lower level things, like providing questions, checking answers, getting user input. You can easily replace these with different implementations to make your game code easily adaptable to many different environments and types of questions.

public class QuestionGame {

public static int win, loss;
public static long TotalTime;

public QuestionGenerator questionGenerator;
public UserInterface userInterface;

public static void main(String[] args) 
{

    // Set the question generator to a specific implementation,
    // in your case, "add" questions generator.
    // If you want to change / extend the questions
    // this would be the only place you would have to change :)
    this.questionGenerator = new AdditionQuestionGenerator();

    // We set up your game to use console input as the user input.
    // You can easily replace it with NetworkInterface, WebsiteInterface,
    // Or any kind of user interface really.
    // Make the game run on a microwave? No problem, just create an adapter for that
    // and make it implement the UserInterface interface.
    this.userInterface = new ConsoleInterface();

    // Keep the game loop running until some
    // desired condition is met
    while(this.gameNotFinished())
    {
      // display a single problem
        this.showProblem();
    }

}


// Display a single problem 
public void showProblem() 
{

    // Generate a question with our generator
    Question question = this.questionGenerator.generate();

    // Get the answer from the user interface
    string answer = this.userInterface.getAnswer();

    // Retrieve a Response object based on the answer provided
    // Response will contain data about the answer
    // How long did it take the user to answer?
    // Was the answer correct?
    // Any data like that can be stored there
    Response respone = question.validateAnswer(answer);

    // Update game state based on the Response data
    this.updateGameState(response);
}

// Update the game state based on users response
public void updateGameState(Response response)
{
  // Here you can do anything you want based on the data in the Response

  // User answered correctly? Increment his score!
  if(response.answeredCorrectly())
  {
    this.score++; 
  }

  // Modify the total time based on the Response data
  this.totalTime += response.responseTime();
}

public boolean gameNotFinished()
{
  // Some logic you would want to use for determining whether the game has ended.
}
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.