Если вам нужен способ динамического задания вопроса со случайными числами и операторами, вы можете создать перечисление Operator
, как показано ниже, для обработки вычисления значения для левой и правой руки.
Также, звонки на System.out.print
должны быть как можно больше в основной программе. Вместо этого вы должны вернуть строки из Question
.
Все, что вам нужно сделать, это передать два случайно сгенерированных числа в перечисление Operator и попросить его вычислить результат.
Экзамен (основной)
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;
}
}
Вопрос (класс)
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);
}
}
Оператор (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;
}
}
Операция (интерфейс)
package exam;
public interface Operation {
double calculate(double left, double right);
}