完成了生成四則運算的程式
分為QixunluGUI類主程式完成介面顯示,QuestionGenerator類題目父類,Grade2QuestionGenerator類實現二年級的題目生成繼承QuestionGenerator類
Grade3QuestionGenerator類實現三年級的題目生成繼承Grade2QuestionGenerator類,Grade4QuestionGenerator類實現三年級的題目生成繼承Grade3QuestionGenerator類
QuestionGeneratorFactory類題目生成防止報錯
具體程式碼如下:
QixunluGUI類
點選檢視程式碼
package qixun;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.Timer;
public class QixunluGUI extends JFrame {
private static final int TIME_LIMIT = 60;
private int questionCount;
private String[] questions;
private double[] correctAnswers;
private JTextField[] answerFields;
private JLabel[] resultLabels;
private JLabel timerLabel = new JLabel("剩餘時間: " + TIME_LIMIT + "秒");
private int correctCount = 0;
private int timeRemaining = TIME_LIMIT;
// 錯題記錄集
private List<MistakeRecord> mistakeList = new ArrayList<>();
public QixunluGUI(int questionCount, int gradeLevel) {
this.questionCount = questionCount;
this.questions = new String[questionCount];
this.correctAnswers = new double[questionCount];
this.answerFields = new JTextField[questionCount];
this.resultLabels = new JLabel[questionCount];
setTitle("數學測驗");
setSize(500, 700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
// 生成問題
QuestionGenerator generator = QuestionGeneratorFactory.createGenerator(gradeLevel);
for (int i = 0; i < questionCount; i++) {
questions[i] = generator.getQuestion();
correctAnswers[i] = generator.getAnswer(questions[i]);
}
// 建立一個皮膚用於問題佈局,三道題一行
JPanel questionPanel = new JPanel(new GridLayout((questionCount + 2) / 3, 4));
for (int i = 0; i < questionCount; i++) {
questionPanel.add(new JLabel("問題 " + (i + 1) + ": " + questions[i]));
answerFields[i] = new JTextField(10);
questionPanel.add(answerFields[i]);
resultLabels[i] = new JLabel();
questionPanel.add(resultLabels[i]);
JButton checkButton = new JButton("提交");
int finalI = i;
checkButton.addActionListener(e -> submitSingleAnswer(finalI, resultLabels[finalI]));
questionPanel.add(checkButton);
}
// 建立一個皮膚用於放置總提交按鈕
JPanel submitPanel = new JPanel(new FlowLayout());
JButton finalSubmitButton = new JButton("提交所有答案");
JButton retryMistakesButton = new JButton("錯題重練");
JLabel finalResultLabel = new JLabel();
// 處理倒數計時
Timer timer = new Timer(1000, e -> {
timeRemaining--;
timerLabel.setText("剩餘時間: " + timeRemaining + "秒");
if (timeRemaining <= 0) {
((Timer) e.getSource()).stop();
JOptionPane.showMessageDialog(null, "時間到!");
submitAllAnswers(finalResultLabel);
}
});
timer.start();
// 設定總提交按鈕事件
finalSubmitButton.addActionListener(e -> {
timer.stop();
submitAllAnswers(finalResultLabel);
});
// 設定錯題重練按鈕事件
retryMistakesButton.addActionListener(e -> retryMistakes());
// 將按鈕和結果標籤加入提交皮膚
submitPanel.add(finalSubmitButton);
submitPanel.add(retryMistakesButton);
submitPanel.add(finalResultLabel);
add(timerLabel, BorderLayout.NORTH);
add(new JScrollPane(questionPanel), BorderLayout.CENTER); // 新增問題皮膚
add(submitPanel, BorderLayout.SOUTH); // 提交按鈕單獨一行
setVisible(true);
}
// 提交單個答案
private void submitSingleAnswer(int index, JLabel resultLabel) {
try {
double userAnswer = Double.parseDouble(answerFields[index].getText());
if (Math.abs(userAnswer - correctAnswers[index]) < 0.001) {
correctCount++;
resultLabel.setText("正確");
} else {
resultLabel.setText("錯誤,正確答案是: " + correctAnswers[index]);
// 記錄錯題
mistakeList.add(new MistakeRecord(questions[index], correctAnswers[index], userAnswer));
}
} catch (NumberFormatException ex) {
resultLabel.setText("請輸入有效的數字");
}
}
// 提交所有答案
private void submitAllAnswers(JLabel finalResultLabel) {
finalResultLabel.setText("總正確率: " + (correctCount / (double) questionCount * 100) + "%");
}
// 錯題重練功能
private void retryMistakes() {
if (mistakeList.isEmpty()) {
JOptionPane.showMessageDialog(this, "沒有錯題可以重練!");
return;
}
JFrame retryFrame = new JFrame("錯題重練");
retryFrame.setSize(400, 400);
retryFrame.setLayout(new GridLayout(mistakeList.size(), 3));
// 重練錯題
for (MistakeRecord mistake : mistakeList) {
retryFrame.add(new JLabel("題目: " + mistake.getQuestion()));
JTextField retryAnswerField = new JTextField(10);
retryFrame.add(retryAnswerField);
JLabel retryResultLabel = new JLabel();
retryFrame.add(retryResultLabel);
JButton retryCheckButton = new JButton("重練提交");
retryCheckButton.addActionListener(e -> {
try {
double retryAnswer = Double.parseDouble(retryAnswerField.getText());
if (Math.abs(retryAnswer - mistake.getCorrectAnswer()) < 0.001) {
retryResultLabel.setText("正確");
} else {
retryResultLabel.setText("錯誤,正確答案是: " + mistake.getCorrectAnswer());
mistake.incrementAttempt(); // 增加錯題重練次數
}
} catch (NumberFormatException ex) {
retryResultLabel.setText("請輸入有效的數字");
}
});
retryFrame.add(retryCheckButton);
}
retryFrame.setVisible(true);
}
// 錯題記錄類
private static class MistakeRecord {
private String question;
private double correctAnswer;
private double userAnswer;
private int attemptCount = 1; // 錯題初始嘗試次數
public MistakeRecord(String question, double correctAnswer, double userAnswer) {
this.question = question;
this.correctAnswer = correctAnswer;
this.userAnswer = userAnswer;
}
public String getQuestion() {
return question;
}
public double getCorrectAnswer() {
return correctAnswer;
}
public int getAttemptCount() {
return attemptCount;
}
public void incrementAttempt() {
attemptCount++;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean flag = true;
while (flag) {
System.out.print("請輸入題目數量: ");
int questionCount = scanner.nextInt();
System.out.print("請輸入年級(2-4): ");
int gradeLevel = scanner.nextInt();
new QixunluGUI(questionCount, gradeLevel);
System.out.println("再來一次(輸入yse)");
String angan=scanner.next();
if(angan.equals("yes")){
flag = true;
}else {
flag = false;
}
}
}
}
點選檢視程式碼
package qixun;
import java.util.*;
public abstract class QuestionGenerator {
protected int operandCount;
protected int maxOperandValue;
protected boolean allowMultiplication;
protected boolean allowDivision;
// 抽象方法,子類需要實現具體的題目生成邏輯
public abstract String getQuestion();
// 獲取題目的答案
public abstract double getAnswer(String question);
}
點選檢視程式碼
package qixun;
import java.util.Random;
public class Grade2QuestionGenerator extends QuestionGenerator {
public Grade2QuestionGenerator() {
this.operandCount = 2; // 運算元為兩個
this.maxOperandValue = 100; // 運算元範圍不超過100
this.allowMultiplication = true;
this.allowDivision = true;
}
@Override
public String getQuestion() {
Random random = new Random();
int operand1 = random.nextInt(maxOperandValue) + 1;
int operand2 = random.nextInt(maxOperandValue) + 1;
String operator = generateOperator(); // 使用生成的運算子
// 確保除法時可以整除且不超過100
if (operator.equals("/")) {
while (operand1 % operand2 != 0 || operand1 > 100) {
operand1 = random.nextInt(maxOperandValue) + 1;
operand2 = random.nextInt(maxOperandValue) + 1;
}
}
return operand1 + " " + operator + " " + operand2;
}
@Override
public double getAnswer(String question) {
String[] parts = question.split(" ");
int operand1 = Integer.parseInt(parts[0]);
String operator = parts[1];
int operand2 = Integer.parseInt(parts[2]);
switch (operator) {
case "+":
return operand1 + operand2;
case "-":
return operand1 - operand2;
case "*":
return operand1 * operand2;
case "/":
return (double) operand1 / operand2;
default:
throw new IllegalArgumentException("無效的運算子!");
}
}
protected String generateOperator() {
Random random = new Random();
String[] operators = {"+", "-", "*", "/"};
return operators[random.nextInt(operators.length)];
}
}
點選檢視程式碼
package qixun;
import java.util.Random;
public class Grade3QuestionGenerator extends Grade2QuestionGenerator {
public Grade3QuestionGenerator() {
this.operandCount = 4; // 運算元不超過4個
this.maxOperandValue = 1000; // 運算元範圍不超過1000
}
@Override
public String getQuestion() {
Random random = new Random();
StringBuilder question = new StringBuilder();
// 生成最多4個運算元的表示式
for (int i = 0; i < operandCount - 1; i++) {
int operand = random.nextInt(maxOperandValue) + 1;
String operator = generateOperator(); // 呼叫父類的 generateOperator()
question.append(operand).append(" ").append(operator).append(" ");
}
question.append(random.nextInt(maxOperandValue) + 1); // 最後一個運算元
return question.toString();
}
@Override
public double getAnswer(String question) {
double result = super.getAnswer(question);
// 確保結果不超過10000
if (result > 10000) {
throw new IllegalArgumentException("結果不能超過10000!");
}
return result;
}
}
點選檢視程式碼
package qixun;
import java.util.*;
public class Grade4QuestionGenerator extends Grade3QuestionGenerator {
public Grade4QuestionGenerator() {
this.operandCount = 5;
}
@Override
public String getQuestion() {
Random random = new Random();
StringBuilder question = new StringBuilder();
// 生成最多5個運算元的表示式,並可能加入括號
boolean useBrackets = random.nextBoolean();
if (useBrackets) {
question.append("(");
}
for (int i = 0; i < operandCount - 1; i++) {
int operand = random.nextInt(maxOperandValue) + 1;
String operator = generateOperator();
question.append(operand).append(" ").append(operator).append(" ");
if (useBrackets && i == 2) {
question.append(") ");
useBrackets = false; // 防止括號重複使用
}
}
question.append(random.nextInt(maxOperandValue) + 1); // 最後一個運算元
return question.toString();
}
}
點選檢視程式碼
package qixun;
public class QuestionGeneratorFactory {
public static QuestionGenerator createGenerator(int gradeLevel) {
switch (gradeLevel) {
case 2:
return new Grade2QuestionGenerator();
case 3:
return new Grade3QuestionGenerator();
case 4:
return new Grade4QuestionGenerator();
default:
throw new IllegalArgumentException("年級只能是2, 3或4");
}
}
}