简体   繁体   中英

Create a simple math game using java objects

I am trying to create a Simple math game using Java objects. My goal is to create a question class, which contains a method to show a question with random numbers, a method to check the answer, a question constructure. How can I generate 10 random questions using these objects? With additions, substraction and multiplication questions. And print the how many correct answers, at the end.

I have created my question class and my first method shows a random question using the variables "a" and "b". and store the answer. My second method check the answer with the user input and print the result. So far when I run my program it only shows the same question over and over again.

This is my Question class

import java.util.*;

public class Question {
    private int a;
    private int b;
    private String Question;
    private int correct;
    Random rand = new Random();
    Scanner input = new Scanner(System.in);
    int count = 0;

    Question(int c, int d) {
        x = rand.nextInt(20);
        y = rand.nextInt(20);
    }

    public void askQuestion() {
        if (a > b) {
            System.out.println("What is " + a + " - " + b + " ?\n");
            correct = a - b;
        } else {
            System.out.println("What is " + a + " + " + b + " ?\n");
            correct = a + b;
        }
    }

    public void Check() {
        int response = Integer.parseInt(input.next());
        if (response == correct) {
            System.out.printf("yes.\n");
            count++;
        } else {
            System.out.printf("No. It is " + correct + ".\n");
        }
    }
}

my main method looks like this

public class Main {
    public static void main(String[] args) {
        Question q1 = new Question(1,2);
        for (int i = 1; i < 10; i++) {
            q1.askQuestion();
            q1.check();
        }
    }
}

In my output it shows the question with two random numbers but it prints the same question over and over again. EX:

What is 13 - 1 ?

12
That is correct.
What is 13 - 1 ?

12
That is correct.
What is 13 - 1 ?

3
Wrong!. The answer is 12.
What is 13 - 1 ?

Eventually I want my output to look like:

What is 4 + 6?

What is 7 - 3?

Any help to fix this? and make this game more interactive? Appreciate it.

Your problem is due to the fact that you are creating one Question object, that generates two random numbers (13 and 1 in your case). You then go through a loop of asking 10 Questions, but you use the same Question object - so you are using the same random numbers every time. To fix this, do the following changes:

In your Question constructor, get rid of the parameters, you do not need them. Assign to variables a and b :

    private Question(){
        a = rand.nextInt(20);
        b = rand.nextInt(20);
    }

So every time you create a Question, you will generate two random numbers which you assign to your variables you declared earlier in the code at the top (in your code, a and b are declared, but not used).

Then in your main, change it to the following:

public static void main(String[] args) {
    for(int i = 0; i < 10; i++) {
        Question q1 = new Question();
        q1.askQuestion();
        q1.check();
    }
    System.out.println("Number correct: " + count); //print amount correct, to use this make variable "count" static.
}

The changes are that now you are creating a new Question object every time you go through the loop, and get new random values. Every time it asks a new Question, it will create a new Question object with new random values and overwrite the old ones. It will ask the question 10 times after you give and check the answer, after which the program will output number of correct answers and stop.

Example output for 3 questions:

What is 17 - 15 ?

2
yes.
What is 8 + 11 ?

19
yes.
What is 9 - 0 ?

5
No. It is 9.
Number correct: 2

If you want a way to dynamically ask a question with random numbers and operators, you can create an Operator enum as seen below to handle calculating the result of a left-hand and right-hand value.

Also, the calls to System.out.print should be in the main program as much as possible. Instead, you should return strings from the Question .

All you need to do is pass the two randomly-generated numbers to the Operator enum and ask it to calculate the result.

Exam (main)

package exam;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Exam {
    private static int correctCount = 0;
    private static List<Question> questions = randomQuestions(10);

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        questions.stream().forEach(question -> ask(question, input));
        input.close();
        stats();
    }

    private static void ask(Question question, Scanner input) {
        System.out.print(question.askQuestion());
        double guess = input.nextDouble();
        boolean isCorrect = question.makeGuess(guess);
        System.out.println(question.explain(isCorrect));
        System.out.println();
        correctCount += isCorrect ? 1 : 0;
    }

    private static void stats() {
        double percentage = (correctCount * 1.0d) / questions.size() * 100;
        System.out.printf("Correct: %.2f%% (%d/%d)%n", percentage, correctCount, questions.size());
    }

    private static List<Question> randomQuestions(int count) {
        List<Question> questions = new ArrayList<Question>();
        while (count --> 0) questions.add(new Question());
        return questions;
    }
}

Question (class)

package exam;

import java.util.Random;

public class Question {
    private static final Random RAND = new Random(System.currentTimeMillis());

    private double left;
    private double right;
    private Operator operator;

    public Question(double left, double right, Operator operator) {
        this.left = left;
        this.right = right;
        this.operator = operator;
    }

    public Question(int max) {
        this(randInt(max), randInt(max), Operator.randomOperator());
    }

    public Question() {
        this(10); // Random 0 -> 10
    }

    public String askQuestion() {
        return String.format("What is %s? ", operator.expression(left, right));
    }

    public String explain(boolean correct) {
        return correct ? "Correct" : String.format("Incorrect, it is: %.2f", calculate());
    }

    public boolean makeGuess(double guess) {
        return compareDouble(guess, calculate(), 0.01);
    }

    private double calculate() {
        return operator.calculate(left, right);
    }

    @Override
    public String toString() {
        return String.format("%s = %.2f", operator.expression(left, right), calculate());
    }

    private static boolean compareDouble(double expected, double actual, double threshold) {
        return Math.abs(expected - actual) < threshold;
    }

    private static double randInt(int range) {
        return Math.floor(RAND.nextDouble() * range);
    }
}

Operator (enum)

package exam;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public enum Operator {
    ADD("+", (left, right) -> left + right),
    SUB("-", (left, right) -> left - right),
    MUL("*", (left, right) -> left * right),
    DIV("/", (left, right) -> left / right);

    private static final Random RAND = new Random(System.currentTimeMillis());
    private static final List<Operator> VALUES = Collections.unmodifiableList(Arrays.asList(values()));
    private static final int SIZE = VALUES.size();

    public static Operator randomOperator() {
        return VALUES.get(RAND.nextInt(SIZE));
    }

    private String symbol;
    private Operation operation;

    private Operator(String symbol, Operation operation) {
        this.symbol = symbol;
        this.operation = operation;
    }

    public double calculate(double left, double right) {
        return operation.calculate(left, right);
    }

    public String expression(double left, double right) {
        return String.format("%.2f %s %.2f", left, symbol, right);
    }

    @Override
    public String toString() {
        return symbol;
    }
}

Operation (interface)

package exam;

public interface Operation {
    double calculate(double left, double right); 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM