10月12日记录

pygmy-killer-whale / 2024-10-13 / 原文

一个能够生成30道四则运算的程序,拥有可视化界面,计分是计算正确数量与错误数量;

点击查看代码
package RandomMathQuiz.java;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import java.util.List;
public class Quizapp extends JFrame {

    private static final int QUESTION_COUNT = 30;
    private static final int TIME_LIMIT_SECONDS = 60;

    private List<Question> questions;
    private int currentQuestionIndex = 0;
    private JLabel questionLabel;
    private JTextField answerField;
    private JButton submitButton;
    private JButton nextButton;
    private JLabel timerLabel;
    private JLabel resultLabel;
    private JLabel correctCountLabel;
    private JLabel incorrectCountLabel;
    private int correctCount = 0;
    private int incorrectCount = 0;

    private ScheduledExecutorService timerService;

    public Quizapp() {
        super("Math Quiz");

        setLayout(new FlowLayout());
        questionLabel = new JLabel("Question: ");
        answerField = new JTextField(10);
        submitButton = new JButton("Submit");
        nextButton = new JButton("Next");
        timerLabel = new JLabel("Time left: " + TIME_LIMIT_SECONDS + " seconds");
        resultLabel = new JLabel("");
        correctCountLabel = new JLabel("Correct: 0");
        incorrectCountLabel = new JLabel("Incorrect: 0");

        submitButton.addActionListener(new SubmitButtonListener());
        nextButton.addActionListener(new NextButtonListener());
        nextButton.setEnabled(false);

        add(questionLabel);
        add(answerField);
        add(submitButton);
        add(nextButton);
        add(timerLabel);
        add(resultLabel);
        add(correctCountLabel);
        add(incorrectCountLabel);

        setSize(400, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        questions = generateQuestions();
        updateQuestion();
        timerService = Executors.newScheduledThreadPool(1);
        timerService.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                int timeLeft = TIME_LIMIT_SECONDS - (currentQuestionIndex * (TIME_LIMIT_SECONDS / QUESTION_COUNT));
                timerLabel.setText("Time left: " + timeLeft + " seconds");
                if (timeLeft <= 0) {
                    nextQuestion();
                }
            }
        }, 0, (1000 * QUESTION_COUNT) / TIME_LIMIT_SECONDS, TimeUnit.MILLISECONDS);
    }

    private void updateQuestion() {
        if (currentQuestionIndex < questions.size()) {
            questionLabel.setText(questions.get(currentQuestionIndex).toString());
            answerField.setText("");
            answerField.requestFocus();
        } else {
            timerService.shutdownNow();
            submitButton.setEnabled(false);
            nextButton.setEnabled(false);
            resultLabel.setText("Quiz complete.");
            correctCountLabel.setText("Correct: " + correctCount);
            incorrectCountLabel.setText("Incorrect: " + incorrectCount);
        }
    }

    private void nextQuestion() {
        if (currentQuestionIndex < questions.size()) {
            currentQuestionIndex++;
            if (currentQuestionIndex == questions.size()) {
                nextButton.setEnabled(false);
            }
            updateQuestion();
        }
    }

    private List<Question> generateQuestions() {
        List<Question> questions = new ArrayList<>();
        Set<String> seen = new HashSet<>();
        while (questions.size() < QUESTION_COUNT) {
            int a = randomInt(1, 100);
            int b = randomInt(1, 100);
            char op = getValidOperation(a, b);
            if (seen.add(createQuestionKey(a, b, op))) {
                questions.add(new Question(a, b, op));
            }
        }
        return questions;
    }

    private int randomInt(int min, int max) {
        return (int) (Math.random() * (max - min + 1) + min);
    }

    private char getValidOperation(int a, int b) {
        if (a >= b && a - b >= 0) {
            return '-';
        } else if (a * b < 1000) {
            return '*';
        } else if (b != 0 && a % b == 0) {
            return '/';
        } else {
            return '+';
        }
    }

    private String createQuestionKey(int a, int b, char op) {
        return a + "-" + b + "-" + op;
    }

    private class SubmitButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            int userAnswer = Integer.parseInt(answerField.getText());
            int correctAnswer = solve(questions.get(currentQuestionIndex));
            if (userAnswer == correctAnswer) {
                correctCount++;
                correctCountLabel.setText("Correct: " + correctCount);
                nextQuestion();
            } else {
                incorrectCount++;
                incorrectCountLabel.setText("Incorrect: " + incorrectCount);
                nextQuestion();
            }
        }
    }

    private class NextButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            nextQuestion();
        }
    }

    public static int solve(Question q) {
        switch (q.op) {
            case '+':
                return q.a + q.b;
            case '-':
                return q.a - q.b;
            case '*':
                return q.a * q.b;
            case '/':
                return q.a / q.b;
            default:
                throw new IllegalStateException("Unexpected value: " + q.op);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Quizapp app = new Quizapp();
            app.setVisible(true);
        });
    }

    static class Question {
        int a, b;
        char op;

        public Question(int a, int b, char op) {
            this.a = a;
            this.b = b;
            this.op = op;
        }

        @Override
        public String toString() {
            return a + " " + op + " " + b + " = ?";
        }
    }
}