Merge branch 'refs/heads/liwentao_branch' into develop

# Conflicts:
#	data/users.txt
develop
Teptao 4 months ago
commit 1b8ce52213

@ -103,7 +103,7 @@ public class MathApp extends JFrame {
// 设置现代化UI外观
FlatLightLaf.setup();
// 全局UI定制
UIManager.put("Button.arc", 999);
UIManager.put("Button.arc", 15);
UIManager.put("Component.arc", 15);
UIManager.put("ProgressBar.arc", 999);
UIManager.put("TextComponent.arc", 15);

@ -20,10 +20,10 @@ public class ChangePasswordPanel extends JPanel {
GridBagConstraints gbc = new GridBagConstraints();
JLabel titleLabel = new JLabel("修改密码", SwingConstants.CENTER);
titleLabel.setFont(new Font("思源黑体", Font.BOLD, 32));
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 32));
JLabel infoLabel = new JLabel("新密码需6-10位且包含大小写字母和数字", SwingConstants.CENTER);
infoLabel.setFont(new Font("思源黑体", Font.PLAIN, 12));
infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
oldPasswordField = new JPasswordField(20);
newPasswordField = new JPasswordField(20);

@ -24,11 +24,11 @@ public class LoginPanel extends JPanel {
passwordField = new JPasswordField(20);
JButton loginButton = new JButton("登录");
loginButton.setFont(new Font("思源黑体", Font.PLAIN, 16));
loginButton.setFont(new Font("微软雅黑", Font.PLAIN, 16));
loginButton.setPreferredSize(new Dimension(120, 40));
JButton registerButton = new JButton("没有账户?立即注册");
registerButton.setFont(new Font("思源黑体", Font.PLAIN, 12));
registerButton.setFont(new Font("微软雅黑", Font.PLAIN, 12));
registerButton.setBorderPainted(false);
registerButton.setContentAreaFilled(false);
registerButton.setFocusPainted(false);
@ -83,7 +83,7 @@ public class LoginPanel extends JPanel {
}
User user = DataPersistence.findUserByEmail(email);
if (user != null && user.verifyPassword(password)||true) {
if (user != null && user.verifyPassword(password)) {
app.setCurrentUserEmail(email);
app.showPanel(MathApp.MAIN_MENU_PANEL);
} else {

@ -24,7 +24,7 @@ public class QuizPanel extends JPanel {
// 顶部面板:进度条和题号
JPanel topPanel = new JPanel(new BorderLayout());
questionLabel = new JLabel("题目 1/" + questionCount + ": ", SwingConstants.LEFT);
questionLabel.setFont(new Font("思源黑体", Font.BOLD, 20));
questionLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
progressBar = new JProgressBar(0, questionCount);
progressBar.setValue(0);
progressBar.setStringPainted(true);
@ -38,7 +38,7 @@ public class QuizPanel extends JPanel {
optionButtons = new JRadioButton[4];
for (int i = 0; i < 4; i++) {
optionButtons[i] = new JRadioButton();
optionButtons[i].setFont(new Font("思源黑体", Font.PLAIN, 16));
optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 16));
optionsGroup.add(optionButtons[i]);
centerPanel.add(optionButtons[i]);
centerPanel.add(Box.createVerticalStrut(10));
@ -67,7 +67,7 @@ public class QuizPanel extends JPanel {
}
public void displayQuestion(Question question, int currentQuestionIndex, int totalQuestions) {
questionLabel.setText(String.format("题目 %d/%d: %s", currentQuestionIndex + 1, totalQuestions, question.problemStatement()));
questionLabel.setText(String.format("题目 %d/%d: %s", currentQuestionIndex + 1, totalQuestions, question.problemStatement()));
progressBar.setValue(currentQuestionIndex);
java.util.List<String> options = question.options();
for (int i = 0; i < optionButtons.length; i++) {

@ -25,7 +25,7 @@ public class RegisterPanel extends JPanel {
titleLabel.setFont(new Font("思源黑体", Font.BOLD, 32));
emailField = new JTextField(20);
codeField = new JTextField(10);
codeField = new JTextField(11);
getCodeButton = new JButton("获取验证码");
JButton registerButton = new JButton("验证并设置密码");
JButton backButton = new JButton("返回登录");

@ -11,14 +11,14 @@ public class ResultsPanel extends JPanel {
GridBagConstraints gbc = new GridBagConstraints();
JLabel titleLabel = new JLabel("测验完成!", SwingConstants.CENTER);
titleLabel.setFont(new Font("思源黑体", Font.BOLD, 32));
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 32));
double percentage = (double) score / totalQuestions * 100;
JLabel scoreLabel = new JLabel(String.format("你的得分: %.0f 分", percentage), SwingConstants.CENTER);
scoreLabel.setFont(new Font("思源黑体", Font.PLAIN, 24));
scoreLabel.setFont(new Font("微软雅黑", Font.PLAIN, 24));
JLabel detailsLabel = new JLabel(String.format("(答对 %d 题,共 %d 题)", score, totalQuestions), SwingConstants.CENTER);
detailsLabel.setFont(new Font("思源黑体", Font.PLAIN, 16));
detailsLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));
JButton againButton = new JButton("返回选择界面");

@ -21,10 +21,10 @@ public class SetPasswordPanel extends JPanel {
GridBagConstraints gbc = new GridBagConstraints();
JLabel titleLabel = new JLabel("设置您的密码", SwingConstants.CENTER);
titleLabel.setFont(new Font("思源黑体", Font.BOLD, 32));
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 32));
JLabel infoLabel = new JLabel("密码需6-10位且包含大小写字母和数字", SwingConstants.CENTER);
infoLabel.setFont(new Font("思源黑体", Font.PLAIN, 12));
infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
passwordField = new JPasswordField(20);
confirmPasswordField = new JPasswordField(20);

@ -63,7 +63,9 @@ public abstract class AbstractProblemGenerator implements IProblemGenerator {
addOperandAndOperator(operands, operators, operator, nonNegativeOnly);
}
addParentheses(operands, operators);
if(nonNegativeOnly) {
addParentheses(operands, operators);
}
return new Equation(operands, operators);
}

@ -4,47 +4,74 @@ import com.mathapp.models.Equation;
import com.mathapp.models.Operator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* /
*
* exp4j
*
*
*/
public class HighSchoolProblemGenerator extends MiddleSchoolProblemGenerator {
private static final int[] PREDEFINED_ANGLES = new int[]{0, 30, 45, 60, 90};
private static final String[] TRIG_FUNCTIONS = new String[]{"sin", "cos", "tan"};
private static final int[] PREDEFINED_ANGLES = {0, 30, 45, 60, 90};
private static final String[] TRIG_FUNCTIONS = {"sin", "cos", "tan"};
@Override
protected Equation createProblem() {
// 复用初中生成器的逻辑,先生成一个带平方或开方的题目
// 1. 调用父类方法生成一个包含平方或开方的基础题目
Equation middleSchoolEquation = super.createProblem();
List<String> operands = new ArrayList<>(middleSchoolEquation.operands());
List<Operator> operators = new ArrayList<>(middleSchoolEquation.operators());
String function = Arrays.toString(TRIG_FUNCTIONS);
int[] angle = PREDEFINED_ANGLES;
String trigExpression;
Operator connectingOperator;
// 生成对学生友好的三角函数表达式,如 "sin(30)"
// exp4j 的计算将在 QuestionGenerator 中通过自定义函数处理角度
String trigExpression = String.format("%s(%d)", function, angle);
// 2.【最终修正策略】使用健壮性检查循环,直到生成一个绝对安全的组合
while (true) {
// 2a. 生成三角函数部分,并确保它不是 tan(90°)
String function;
int angleInDegrees;
do {
function = TRIG_FUNCTIONS[random.nextInt(TRIG_FUNCTIONS.length)];
angleInDegrees = PREDEFINED_ANGLES[random.nextInt(PREDEFINED_ANGLES.length)];
} while (function.equals("tan") && angleInDegrees == 90);
// 随机选择一个位置插入三角函数表达式
int insertPos = random.nextInt(operands.size() + 1);
if (insertPos == operands.size() || operands.isEmpty()) {
operands.add(trigExpression);
if(!operators.isEmpty() || operands.size() > 1) {
operators.add(Operator.ADD);
trigExpression = String.format("%s(%s)", function, getRadianString(angleInDegrees));
// 2b. 随机选择一个连接运算符
connectingOperator = Operator.values()[random.nextInt(Operator.values().length)];
// 2c.【健壮性检查】检查这个新运算符是否会与三角函数的值构成除零错误
boolean isTrigValueZero = (function.equals("sin") && angleInDegrees == 0) ||
(function.equals("tan") && angleInDegrees == 0);
// 如果新运算符是除法且三角函数的值是0则这是一个非法组合必须重试
if (connectingOperator == Operator.DIVIDE && isTrigValueZero) {
continue; // 非法组合,重新循环
}
} else {
operands.add(insertPos, trigExpression);
operators.add(insertPos, Operator.ADD); // 简单地用加法连接
// 如果代码能执行到这里,说明组合是安全的,可以退出循环
break;
}
// 3.【安全的追加操作】将生成的安全组合追加到表达式末尾
// 这种方法永远不会导致 IndexOutOfBoundsException
operands.add(trigExpression);
operators.add(connectingOperator);
return new Equation(operands, operators);
}
/**
* exp4j pi
*/
private String getRadianString(int angleInDegrees) {
switch (angleInDegrees) {
case 0: return "0";
case 30: return "pi/6";
case 45: return "pi/4";
case 60: return "pi/3";
case 90: return "pi/2";
default: return "0";
}
}
}

@ -8,34 +8,38 @@ import java.util.List;
/**
*
*
* exp4j
* (, "(5^2)" "sqrt(25)") exp4j
*/
public class MiddleSchoolProblemGenerator extends AbstractProblemGenerator {
@Override
protected Equation createProblem() {
// 1. 调用父类的核心方法,并传入 false允许生成包含负数的标准表达式。
Equation basicEquation = createBaseArithmeticProblem(false);
// 2. 将基础表达式元素转为可修改的列表
List<String> operands = new ArrayList<>(basicEquation.operands());
List<Operator> operators = new ArrayList<>(basicEquation.operators());
// 3. 随机选择一个操作数进行变形
int modifyIndex = random.nextInt(operands.size());
String targetOperand = operands.get(modifyIndex);
// 检查操作数是否已经是复杂表达式(包含括号),如果是,则不再添加括号
boolean isComplex = targetOperand.contains("(") && targetOperand.contains(")");
String targetOperand = operands.get(modifyIndex).replace("(", "").replace(")", "");
// 4. 随机决定是进行平方还是开方运算
if (random.nextBoolean()) {
// 平方运算exp4j 使用 '^' 符号
// 如果操作数本身是复杂表达式,如 (3+2),则需要保留括号,变成 ((3+2)^2)
String squaredExpression = isComplex? String.format("(%s^2)", targetOperand) : String.format("%s^2", targetOperand);
// 平方运算: 使用 `^` 符号exp4j 支持此格式
String squaredExpression = String.format("(%s^2)", targetOperand);
operands.set(modifyIndex, squaredExpression);
} else {
// 开方运算exp4j 使用 'sqrt()' 函数
// 开方运算: 使用 `sqrt()` 函数exp4j 内置支持此函数
int base = getRandomNumber(2, 10);
int valueToRoot = base * base;
String sqrtExpression = String.format("sqrt(%d)", valueToRoot);
operands.set(modifyIndex, sqrtExpression);
}
// 5. 返回构建好的、与exp4j兼容的方程式
return new Equation(operands, operators);
}
}

Loading…
Cancel
Save