generateQuestions(String level, int count);
}
\ No newline at end of file
diff --git a/src/com/mathlearning/view/QuizFrame.java b/src/com/mathlearning/view/QuizFrame.java
index 48590cf..002e833 100644
--- a/src/com/mathlearning/view/QuizFrame.java
+++ b/src/com/mathlearning/view/QuizFrame.java
@@ -1,6 +1,5 @@
package com.mathlearning.view;
-import com.mathlearning.controller.AuthController;
import com.mathlearning.controller.QuestionController;
import com.mathlearning.model.Question;
import javax.swing.*;
@@ -58,12 +57,23 @@ public class QuizFrame extends JFrame {
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
- // 进度条
+ // 顶部面板(退出按钮和进度条)
+ JPanel topPanel = new JPanel(new BorderLayout());
+
+ JButton exitButton = new JButton("退出答题");
+ exitButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
+ exitButton.setBackground(new Color(220, 100, 100));
+ exitButton.setForeground(Color.WHITE);
+ exitButton.addActionListener(e -> exitQuiz());
+
progressBar = new JProgressBar(0, totalQuestions);
progressBar.setValue(0);
progressBar.setStringPainted(true);
progressBar.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
- mainPanel.add(progressBar, BorderLayout.NORTH);
+
+ topPanel.add(exitButton, BorderLayout.WEST);
+ topPanel.add(progressBar, BorderLayout.CENTER);
+ mainPanel.add(topPanel, BorderLayout.NORTH);
// 问题面板
JPanel questionPanel = new JPanel(new BorderLayout(10, 20));
@@ -84,7 +94,7 @@ public class QuizFrame extends JFrame {
// 选项面板
JPanel optionsPanel = new JPanel(new GridLayout(4, 1, 10, 10));
optionsPanel.setBorder(
- BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY), "请选择答案"));
+ BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.GRAY), "请选择答案"));
optionButtons = new JRadioButton[4];
buttonGroup = new ButtonGroup();
@@ -98,11 +108,11 @@ public class QuizFrame extends JFrame {
final int index = i;
optionButtons[i].addActionListener(
- e -> {
- // 保存当前选择
- userSelections[currentDisplayIndex] = index;
- System.out.println("用户选择: 第" + (currentDisplayIndex + 1) + "题 -> 选项" + index);
- });
+ e -> {
+ // 保存当前选择
+ userSelections[currentDisplayIndex] = index;
+ System.out.println("用户选择: 第" + (currentDisplayIndex + 1) + "题 -> 选项" + index);
+ });
buttonGroup.add(optionButtons[i]);
optionsPanel.add(optionButtons[i]);
@@ -110,7 +120,6 @@ public class QuizFrame extends JFrame {
JPanel optionsContainer = new JPanel(new FlowLayout(FlowLayout.CENTER));
optionsContainer.add(optionsPanel);
- mainPanel.add(optionsContainer, BorderLayout.SOUTH);
// 控制面板
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
@@ -141,23 +150,7 @@ public class QuizFrame extends JFrame {
// 添加事件监听器
previousButton.addActionListener(new PreviousQuestionAction());
nextButton.addActionListener(new NextQuestionAction());
- // 添加顶部退出答题按钮
- JPanel topPanel = new JPanel(new BorderLayout());
- JButton exitButton = new JButton("退出答题");
- exitButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
- exitButton.setBackground(new Color(220, 100, 100));
- exitButton.setForeground(Color.WHITE);
- exitButton.addActionListener(e -> exitQuiz());
-
- progressBar = new JProgressBar(0, totalQuestions);
- progressBar.setValue(0);
- progressBar.setStringPainted(true);
- progressBar.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
-
- topPanel.add(exitButton, BorderLayout.WEST);
- topPanel.add(progressBar, BorderLayout.CENTER);
- mainPanel.add(topPanel, BorderLayout.NORTH);
add(mainPanel);
}
@@ -168,16 +161,16 @@ public class QuizFrame extends JFrame {
}
Question currentQuestion = allQuestions.get(currentDisplayIndex);
questionNumberLabel.setText(
- String.format("第 %d 题 / 共 %d 题", currentDisplayIndex + 1, totalQuestions));
+ String.format("第 %d 题 / 共 %d 题", currentDisplayIndex + 1, totalQuestions));
questionTextLabel.setText(
- ""
- + currentQuestion.getQuestionText()
- + "
");
+ ""
+ + currentQuestion.getQuestionText()
+ + "
");
String[] options = currentQuestion.getOptions();
for (int i = 0; i < 4; i++) {
String optionText =
- String.format(
- "%c. %s
", (char) ('A' + i), options[i]);
+ String.format(
+ "%c. %s
", (char) ('A' + i), options[i]);
optionButtons[i].setText(optionText);
}
buttonGroup.clearSelection(); // 清除当前选择状态
@@ -191,17 +184,17 @@ public class QuizFrame extends JFrame {
// 更新进度条
progressBar.setValue(currentDisplayIndex);
progressBar.setString(
- String.format(
- "%d/%d (%.0f%%)",
- currentDisplayIndex,
- totalQuestions,
- ((double) currentDisplayIndex / totalQuestions) * 100));
+ String.format(
+ "%d/%d (%.0f%%)",
+ currentDisplayIndex,
+ totalQuestions,
+ ((double) currentDisplayIndex / totalQuestions) * 100));
updateButtonStates(); // 更新按钮状态
}
private void exitQuiz() {
int result =
- JOptionPane.showConfirmDialog(this, "确定要退出答题吗?所有进度将丢失。", "退出确认", JOptionPane.YES_NO_OPTION);
+ JOptionPane.showConfirmDialog(this, "确定要退出答题吗?所有进度将丢失。", "退出确认", JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
parentFrame.setVisible(true);
this.dispose();
@@ -245,8 +238,8 @@ public class QuizFrame extends JFrame {
// 如果没有选择答案,提示用户但允许继续(除了最后一题)
if (selectedIndex == -1) {
int result =
- JOptionPane.showConfirmDialog(
- QuizFrame.this, "您还没有选择答案,确定要继续下一题吗?", "确认", JOptionPane.YES_NO_OPTION);
+ JOptionPane.showConfirmDialog(
+ QuizFrame.this, "您还没有选择答案,确定要继续下一题吗?", "确认", JOptionPane.YES_NO_OPTION);
if (result != JOptionPane.YES_OPTION) {
return;
}
@@ -262,52 +255,27 @@ public class QuizFrame extends JFrame {
}
}
- private void submitAllAnswers() { // 直接在本地计算分数
- final int calculatedScore = calculateLocalScore(); // 使用final
- // 创建一个新的QuestionController来显示正确分数
- questionController =
- new QuestionController() {
- @Override
- public int getScore() {
- return calculatedScore; // 现在可以访问了
- }
-
- @Override
- public int getTotalQuestions() {
- return totalQuestions;
- }
-
- @Override
- public double getPercentage() {
- return (double) calculatedScore / totalQuestions * 100;
- }
-
- @Override
- public int[] getUserAnswers() {
- return userSelections;
- }
-
- @Override
- public java.util.List getCurrentQuestions() {
- return allQuestions;
- }
- };
- }
-
- private int calculateLocalScore() {
+ private void submitAllAnswers() {
+ // 计算分数
int score = 0;
for (int i = 0; i < totalQuestions; i++) {
- if (userSelections[i] != -1 && allQuestions.get(i).isCorrect(userSelections[i])) {
- score++;
+ if (userSelections[i] != -1) {
+ // 使用 QuestionController 来检查答案
+ questionController.setCurrentQuestionIndex(i);
+ if (questionController.submitAnswer(userSelections[i])) {
+ score++;
+ }
}
}
- return score;
+
+ // 重置到第一个问题,以便在结果显示时能正确访问
+ questionController.setCurrentQuestionIndex(0);
}
private void finishQuiz() {
- ScoreFrame scoreFrame =
- new ScoreFrame(questionController, userSelections, allQuestions, parentFrame);
+ // 使用原有的构造函数
+ ScoreFrame scoreFrame = new ScoreFrame(questionController, userSelections, allQuestions, parentFrame);
scoreFrame.setVisible(true);
this.dispose();
}
-}
+} // 添加这个闭合大括号
\ No newline at end of file
diff --git a/src/com/mathlearning/view/ScoreFrame.java b/src/com/mathlearning/view/ScoreFrame.java
index 9e93212..21e9edc 100644
--- a/src/com/mathlearning/view/ScoreFrame.java
+++ b/src/com/mathlearning/view/ScoreFrame.java
@@ -13,10 +13,10 @@ public class ScoreFrame extends JFrame {
private LevelSelectionFrame parentFrame;
public ScoreFrame(
- QuestionController questionController,
- int[] userSelections,
- List allQuestions,
- LevelSelectionFrame parent) {
+ QuestionController questionController,
+ int[] userSelections,
+ List allQuestions,
+ LevelSelectionFrame parent) {
this.parentFrame = parent;
this.questionController = questionController;
this.userSelections = userSelections;
@@ -34,13 +34,13 @@ public class ScoreFrame extends JFrame {
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
- // Score summary
+ // Score summary - 修复这里
int score = questionController.getScore();
int total = questionController.getTotalQuestions();
- double percentage = questionController.getPercentage();
+ double percentage = (double) score / total * 100; // 手动计算百分比
JLabel scoreLabel =
- new JLabel(String.format("得分: %d/%d (%.1f%%)", score, total, percentage), JLabel.CENTER);
+ new JLabel(String.format("得分: %d/%d (%.1f%%)", score, total, percentage), JLabel.CENTER);
scoreLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 24));
Color color;
@@ -62,21 +62,22 @@ public class ScoreFrame extends JFrame {
for (int i = 0; i < allQuestions.size(); i++) {
Question q = allQuestions.get(i);
int userAnswer = userSelections[i];
- boolean isCorrect = (userAnswer != -1) && q.isCorrect(userAnswer);
+ // 修复这里:使用 getCorrectIndex() 而不是 getCorrectAnswerIndex()
+ boolean isCorrect = (userAnswer != -1) && (userAnswer == q.getCorrectIndex());
details.append(String.format("第%d题: %s\n", i + 1, q.getQuestionText()));
details.append(
- String.format(
- "你的答案: %s\n",
- userAnswer == -1
- ? "未作答"
- : (char) ('A' + userAnswer) + ". " + q.getOptions()[userAnswer]));
+ String.format(
+ "你的答案: %s\n",
+ userAnswer == -1
+ ? "未作答"
+ : (char) ('A' + userAnswer) + ". " + q.getOptions()[userAnswer]));
details.append(
- String.format(
- "正确答案: %s\n",
- (char) ('A' + q.getCorrectAnswerIndex())
- + ". "
- + q.getOptions()[q.getCorrectAnswerIndex()]));
+ String.format(
+ "正确答案: %s\n",
+ (char) ('A' + q.getCorrectIndex())
+ + ". "
+ + q.getOptions()[q.getCorrectIndex()]));
details.append(isCorrect ? "✓ 正确\n" : "✗ 错误\n");
details.append("--------------------\n");
}
@@ -108,4 +109,4 @@ public class ScoreFrame extends JFrame {
parentFrame.setVisible(true);
this.dispose();
}
-}
+}
\ No newline at end of file
--
2.34.1
From 46e201e0026110df5125feead89fd6b9b453c8a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9F=B3=E6=84=8F?= <1449892469@qq.com>
Date: Sun, 12 Oct 2025 09:47:04 +0800
Subject: [PATCH 4/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B0=8F=E5=AD=A6?=
=?UTF-8?q?=E9=A2=98=E7=9B=AE=E8=AE=A1=E7=AE=97=E7=B2=BE=E5=BA=A6=E9=97=AE?=
=?UTF-8?q?=E9=A2=98=EF=BC=9A=E5=85=88=E7=B2=BE=E7=A1=AE=E8=AE=A1=E7=AE=97?=
=?UTF-8?q?=E5=86=8D=E4=BF=9D=E7=95=99=E5=B0=8F=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../model/BaseQuestionGenerator.java | 27 +++++++++++++------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/com/mathlearning/model/BaseQuestionGenerator.java b/src/com/mathlearning/model/BaseQuestionGenerator.java
index 88cec22..2a82651 100644
--- a/src/com/mathlearning/model/BaseQuestionGenerator.java
+++ b/src/com/mathlearning/model/BaseQuestionGenerator.java
@@ -36,6 +36,7 @@ public abstract class BaseQuestionGenerator {
return !(answer < 0 || Double.isNaN(answer) || Double.isInfinite(answer));
}
+ // 修改:使用double进行精确计算,只在最后保留小数
protected double calculateExpression(double[] values, int[] operations) {
List numbers = new ArrayList<>();
List ops = new ArrayList<>();
@@ -94,6 +95,7 @@ public abstract class BaseQuestionGenerator {
result = performOperation(result, nextNum, op);
}
+ // 修改:只在最后一步进行四舍五入保留2位小数
return Math.round(result * 100) / 100.0;
}
@@ -104,6 +106,7 @@ public abstract class BaseQuestionGenerator {
case 2: return left * right;
case 3:
if (right == 0) return Double.NaN;
+ // 修改:直接进行除法,不在这里保留小数
return left / right;
default: return left;
}
@@ -113,8 +116,9 @@ public abstract class BaseQuestionGenerator {
String[] options = new String[4];
Set usedValues = new HashSet<>();
- boolean isIntegerAnswer = (answer == (int) answer);
- String correctAnswer = formatAnswer(answer);
+ // 修改:判断是否为整数的逻辑
+ boolean isIntegerAnswer = Math.abs(answer - Math.round(answer)) < 1e-10;
+ String correctAnswer = formatAnswer(answer, isIntegerAnswer);
options[0] = correctAnswer;
usedValues.add(correctAnswer);
@@ -134,7 +138,8 @@ public abstract class BaseQuestionGenerator {
do {
double wrongValue = generateWrongValue(answer, isIntegerAnswer);
- wrongAnswer = formatAnswer(wrongValue);
+ wrongAnswer = formatAnswer(wrongValue,
+ Math.abs(wrongValue - Math.round(wrongValue)) < 1e-10);
attempts++;
} while (usedValues.contains(wrongAnswer) && attempts < 20);
@@ -147,20 +152,26 @@ public abstract class BaseQuestionGenerator {
double offset = (random.nextDouble() * 5) + 1;
if (isIntegerAnswer) {
- int intAnswer = (int) answer;
+ int intAnswer = (int) Math.round(answer);
int intOffset = random.nextInt(10) + 1;
double wrongValue = random.nextBoolean() ?
intAnswer + intOffset : Math.max(1, intAnswer - intOffset);
- return (int) wrongValue;
+ return wrongValue;
} else {
double wrongValue = random.nextBoolean() ? answer + offset : answer - offset;
+ // 修改:错误选项也保留2位小数
return Math.round(wrongValue * 100) / 100.0;
}
}
- private String formatAnswer(double answer) {
- return (answer == (int) answer) ?
- String.valueOf((int) answer) : String.format("%.2f", answer);
+ // 修改:格式化答案,只在最后一步处理小数位数
+ private String formatAnswer(double answer, boolean isInteger) {
+ if (isInteger) {
+ return String.valueOf((int) Math.round(answer));
+ } else {
+ // 确保显示2位小数,即使末尾是0
+ return String.format("%.2f", answer);
+ }
}
private void shuffleArray(String[] array) {
--
2.34.1
From 163c67305d6362360073a652fe469bc5f29c9907 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9F=B3=E6=84=8F?= <1449892469@qq.com>
Date: Sun, 12 Oct 2025 10:01:36 +0800
Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B0=8F=E5=AD=A6?=
=?UTF-8?q?=E9=A2=98=E7=9B=AE=E8=AE=A1=E7=AE=97=E7=B2=BE=E5=BA=A6=E9=97=AE?=
=?UTF-8?q?=E9=A2=98=EF=BC=9A=E9=99=A4=E6=B3=95=E9=99=A4=E6=95=B0=E6=8E=A5?=
=?UTF-8?q?=E8=BF=910=E6=97=B6=E4=B8=8D=E8=A2=AB=E8=88=8D=E5=8E=BB?=
=?UTF-8?q?=E8=80=8C=E5=AF=BC=E8=87=B4=E7=BB=93=E6=9E=9C=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../model/PrimaryQuestionGenerator.java | 35 ++++++++++++++-----
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/com/mathlearning/model/PrimaryQuestionGenerator.java b/src/com/mathlearning/model/PrimaryQuestionGenerator.java
index cdcaaad..675322f 100644
--- a/src/com/mathlearning/model/PrimaryQuestionGenerator.java
+++ b/src/com/mathlearning/model/PrimaryQuestionGenerator.java
@@ -87,10 +87,11 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
}
private double calculateWithParentheses(int[] operands, int[] operations, int parenStart, int parenEnd) {
- List numbers = new ArrayList<>();
+ // 修改:使用Double列表
+ List numbers = new ArrayList<>();
List ops = new ArrayList<>();
- for (int operand : operands) numbers.add(operand);
+ for (int operand : operands) numbers.add((double) operand);
for (int operation : operations) ops.add(operation);
double parenthesesResult = calculateParenthesesContent(numbers, ops, parenStart, parenEnd);
@@ -98,20 +99,22 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
if (!isValidAnswer(parenthesesResult)) return -1;
replaceWithParenthesesResult(numbers, ops, parenStart, parenEnd, parenthesesResult);
- return calculateWithoutParentheses(numbers, ops);
+ // 修改:调用新的方法名
+ return calculateDoubleList(numbers, ops);
}
- private double calculateParenthesesContent(List numbers, List ops, int start, int end) {
- List parenNumbers = new ArrayList<>();
+ private double calculateParenthesesContent(List numbers, List ops, int start, int end) {
+ List parenNumbers = new ArrayList<>();
List parenOps = new ArrayList<>();
for (int i = start; i <= end; i++) parenNumbers.add(numbers.get(i));
for (int i = start; i < end; i++) parenOps.add(ops.get(i));
- return calculateWithoutParentheses(parenNumbers, parenOps);
+ // 修改:调用新的方法名
+ return calculateDoubleList(parenNumbers, parenOps);
}
- private void replaceWithParenthesesResult(List numbers, List ops,
+ private void replaceWithParenthesesResult(List numbers, List ops,
int start, int end, double result) {
int numCountToRemove = end - start + 1;
int opCountToRemove = end - start;
@@ -119,6 +122,22 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
for (int i = 0; i < numCountToRemove; i++) numbers.remove(start);
for (int i = 0; i < opCountToRemove; i++) ops.remove(start);
- numbers.add(start, (int) Math.round(result));
+ // 修改:直接添加double结果,不转换为int
+ numbers.add(start, result);
+ }
+
+ // 修改:重命名方法,避免与父类冲突
+ private double calculateDoubleList(List numbers, List ops) {
+ double[] doubleNumbers = new double[numbers.size()];
+ for (int i = 0; i < numbers.size(); i++) {
+ doubleNumbers[i] = numbers.get(i);
+ }
+
+ int[] intOps = new int[ops.size()];
+ for (int i = 0; i < ops.size(); i++) {
+ intOps[i] = ops.get(i);
+ }
+
+ return calculateExpression(doubleNumbers, intOps);
}
}
\ No newline at end of file
--
2.34.1