diff --git a/src/main/java/com/example/mathsystemtogether/ChangePasswordController.java b/src/main/java/com/example/mathsystemtogether/ChangePasswordController.java index f8f9269..56c8c1d 100644 --- a/src/main/java/com/example/mathsystemtogether/ChangePasswordController.java +++ b/src/main/java/com/example/mathsystemtogether/ChangePasswordController.java @@ -1,149 +1,149 @@ -package com.example.mathsystemtogether; - -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; -import javafx.scene.control.*; -import javafx.stage.Stage; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.List; - -public class ChangePasswordController { - - @FXML - private TextField usernameField; - - @FXML - private PasswordField oldPasswordField; - - @FXML - private PasswordField newPasswordField; - - @FXML - private PasswordField confirmNewPasswordField; - - @FXML - private Button changePasswordButton; - - @FXML - private Button cancelButton; - - @FXML - private Label statusLabel; - - private String currentUser; - private ExamController examController; - private static final String USER_DATA_FILE = "user_data.txt"; - - public void setCurrentUser(String username) { - this.currentUser = username; - usernameField.setText(username); - } - - public void setExamController(ExamController examController) { - this.examController = examController; - } - - @FXML - private void handleChangePassword() { - String oldPassword = oldPasswordField.getText(); - String newPassword = newPasswordField.getText(); - String confirmNewPassword = confirmNewPasswordField.getText(); - - if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmNewPassword.isEmpty()) { - showStatus("请填写所有字段", true); - return; - } - - if (!examController.checkUserPassword(currentUser, oldPassword)) { - showStatus("原密码错误", true); - return; - } - - if (newPassword.length() < 6) { - showStatus("新密码至少需要6个字符", true); - return; - } - - if (!newPassword.equals(confirmNewPassword)) { - showStatus("两次输入的新密码不一致", true); - return; - } - - if (oldPassword.equals(newPassword)) { - showStatus("新密码不能与原密码相同", true); - return; - } - - if (updatePassword(currentUser, newPassword)) { - showStatus("密码修改成功!", false); - - // 延迟关闭窗口 - new java.util.Timer().schedule( - new java.util.TimerTask() { - @Override - public void run() { - javafx.application.Platform.runLater(() -> { - handleClose(); - }); - } - }, - 1500 - ); - } else { - showStatus("密码修改失败,请重试", true); - } - } - - @FXML - private void handleCancel() { - handleClose(); - } - - private void handleClose() { - Stage stage = (Stage) cancelButton.getScene().getWindow(); - stage.close(); - } - - private boolean updatePassword(String username, String newPassword) { - try { - // 读取所有用户数据 - List lines = Files.readAllLines(Paths.get(USER_DATA_FILE)); - boolean userFound = false; - - for (int i = 0; i < lines.size(); i++) { - String[] parts = lines.get(i).split("\\|"); - if (parts.length >= 2 && parts[0].equals(username)) { - // 更新密码 - parts[1] = newPassword; - lines.set(i, String.join("|", parts)); - userFound = true; - break; - } - } - - if (userFound) { - // 写回文件 - Files.write(Paths.get(USER_DATA_FILE), lines); - // 更新内存中的用户数据 - examController.updateUserPassword(username, newPassword); - return true; - } - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - - private void showStatus(String message, boolean isError) { - statusLabel.setText(message); - if (isError) { - statusLabel.setStyle("-fx-text-fill: #DC143C; -fx-font-weight: bold; -fx-font-size: 14;"); - } else { - statusLabel.setStyle("-fx-text-fill: #228B22; -fx-font-weight: bold; -fx-font-size: 14;"); - } - } -} +package com.example.mathsystemtogether; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.stage.Stage; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.List; + +public class ChangePasswordController { + + @FXML + private TextField usernameField; + + @FXML + private PasswordField oldPasswordField; + + @FXML + private PasswordField newPasswordField; + + @FXML + private PasswordField confirmNewPasswordField; + + @FXML + private Button changePasswordButton; + + @FXML + private Button cancelButton; + + @FXML + private Label statusLabel; + + private String currentUser; + private ExamController examController; + private static final String USER_DATA_FILE = "user_data.txt"; + + public void setCurrentUser(String username) { + this.currentUser = username; + usernameField.setText(username); + } + + public void setExamController(ExamController examController) { + this.examController = examController; + } + + @FXML + private void handleChangePassword() { + String oldPassword = oldPasswordField.getText(); + String newPassword = newPasswordField.getText(); + String confirmNewPassword = confirmNewPasswordField.getText(); + + if (oldPassword.isEmpty() || newPassword.isEmpty() || confirmNewPassword.isEmpty()) { + showStatus("请填写所有字段", true); + return; + } + + if (!examController.checkUserPassword(currentUser, oldPassword)) { + showStatus("原密码错误", true); + return; + } + + if (newPassword.length() < 6) { + showStatus("新密码至少需要6个字符", true); + return; + } + + if (!newPassword.equals(confirmNewPassword)) { + showStatus("两次输入的新密码不一致", true); + return; + } + + if (oldPassword.equals(newPassword)) { + showStatus("新密码不能与原密码相同", true); + return; + } + + if (updatePassword(currentUser, newPassword)) { + showStatus("密码修改成功!", false); + + // 延迟关闭窗口 + new java.util.Timer().schedule( + new java.util.TimerTask() { + @Override + public void run() { + javafx.application.Platform.runLater(() -> { + handleClose(); + }); + } + }, + 1500 + ); + } else { + showStatus("密码修改失败,请重试", true); + } + } + + @FXML + private void handleCancel() { + handleClose(); + } + + private void handleClose() { + Stage stage = (Stage) cancelButton.getScene().getWindow(); + stage.close(); + } + + private boolean updatePassword(String username, String newPassword) { + try { + // 读取所有用户数据 + List lines = Files.readAllLines(Paths.get(USER_DATA_FILE)); + boolean userFound = false; + + for (int i = 0; i < lines.size(); i++) { + String[] parts = lines.get(i).split("\\|"); + if (parts.length >= 2 && parts[0].equals(username)) { + // 更新密码 + parts[1] = newPassword; + lines.set(i, String.join("|", parts)); + userFound = true; + break; + } + } + + if (userFound) { + // 写回文件 + Files.write(Paths.get(USER_DATA_FILE), lines); + // 更新内存中的用户数据 + examController.updateUserPassword(username, newPassword); + return true; + } + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + private void showStatus(String message, boolean isError) { + statusLabel.setText(message); + if (isError) { + statusLabel.setStyle("-fx-text-fill: #DC143C; -fx-font-weight: bold; -fx-font-size: 14;"); + } else { + statusLabel.setStyle("-fx-text-fill: #228B22; -fx-font-weight: bold; -fx-font-size: 14;"); + } + } +} diff --git a/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java b/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java index 9638bad..3d1247f 100644 --- a/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java +++ b/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java @@ -54,12 +54,13 @@ public class ChoiceQuestionGenerator { * 生成小学题目 */ private Question generatePrimaryQuestion(int questionNumber) { - int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE); - int b = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE); - - String operation = getRandomOperation("+*-"); - String questionText = String.format("%d %s %d = ?", a, operation, b); - int correctAnswer = calculate(a, b, operation); + // 随机选择运算符号数量(1-3个) + int operatorCount = 1 + random.nextInt(3); + + // 生成复合运算表达式 + String[] expression = generateCompoundExpression(operatorCount); + String questionText = expression[0]; + int correctAnswer = Integer.parseInt(expression[1]); // 生成错误选项 List options = generateWrongOptions(correctAnswer); @@ -79,13 +80,52 @@ public class ChoiceQuestionGenerator { * 生成初中题目 */ private Question generateJuniorQuestion(int questionNumber) { - int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE); + // 随机选择运算符号数量(1-3个) + int operatorCount = 1 + random.nextInt(3); + + // 30%概率生成平方/开方题目,70%概率生成复合运算题目 + if (random.nextDouble() < 0.3) { + // 生成平方或开方题目 + if (random.nextBoolean()) { + // 平方题目 + int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE); + String questionText = String.format("%d² = ?", a); + int correctAnswer = a * a; + List options = generateWrongOptions(correctAnswer); + options.add(correctAnswer); + Collections.shuffle(options); + + return new Question(questionText, + String.valueOf(options.get(0)), + String.valueOf(options.get(1)), + String.valueOf(options.get(2)), + String.valueOf(options.get(3)), + String.valueOf(correctAnswer), + questionNumber); + } else { + // 开方题目 + int perfectSquare = (int) Math.pow(random.nextInt(10) + 1, 2); + String questionText = String.format("√%d = ?", perfectSquare); + int correctAnswer = (int) Math.sqrt(perfectSquare); + List options = generateWrongOptions(correctAnswer); + options.add(correctAnswer); + Collections.shuffle(options); + + return new Question(questionText, + String.valueOf(options.get(0)), + String.valueOf(options.get(1)), + String.valueOf(options.get(2)), + String.valueOf(options.get(3)), + String.valueOf(correctAnswer), + questionNumber); + } + } else { + // 生成复合运算表达式(包含除法) + String[] expression = generateCompoundExpressionWithDivision(operatorCount); + String questionText = expression[0]; + int correctAnswer = Integer.parseInt(expression[1]); - // 50%概率生成平方或开方题目 - if (random.nextBoolean()) { - // 平方题目 - String questionText = String.format("%d² = ?", a); - int correctAnswer = a * a; + // 生成错误选项 List options = generateWrongOptions(correctAnswer); options.add(correctAnswer); Collections.shuffle(options); @@ -97,11 +137,49 @@ public class ChoiceQuestionGenerator { String.valueOf(options.get(3)), String.valueOf(correctAnswer), questionNumber); + } + } + + /** + * 生成高中题目 + */ + private Question generateSeniorQuestion(int questionNumber) { + // 随机选择运算符号数量(1-3个) + int operatorCount = 1 + random.nextInt(3); + + // 40%概率生成三角函数题目,60%概率生成复合运算题目 + if (random.nextDouble() < 0.4) { + // 生成三角函数题目 + int[] commonAngles = {0, 30, 45, 60, 90, 120, 135, 150, 180, 210, 225, 270, 300, 315, 330}; + int angle = commonAngles[random.nextInt(commonAngles.length)]; + String[] functions = {"sin", "cos", "tan"}; + String function = functions[random.nextInt(functions.length)]; + + String questionText = String.format("%s(%d°) = ?", function, angle); + double result = calculateTrigFunction(function, angle); + + // 生成选项 + List options = generateTrigOptions(result); + // 使用格式化后的值作为正确答案,确保与选项一致 + String correctAnswer = formatTrigValue(result); + + // 随机打乱选项 + Collections.shuffle(options); + + return new Question(questionText, + options.get(0), + options.get(1), + options.get(2), + options.get(3), + correctAnswer, + questionNumber); } else { - // 开方题目 - int perfectSquare = (int) Math.pow(random.nextInt(10) + 1, 2); - String questionText = String.format("√%d = ?", perfectSquare); - int correctAnswer = (int) Math.sqrt(perfectSquare); + // 生成复合运算表达式(包含更复杂的运算) + String[] expression = generateAdvancedCompoundExpression(operatorCount); + String questionText = expression[0]; + int correctAnswer = Integer.parseInt(expression[1]); + + // 生成错误选项 List options = generateWrongOptions(correctAnswer); options.add(correctAnswer); Collections.shuffle(options); @@ -114,36 +192,6 @@ public class ChoiceQuestionGenerator { String.valueOf(correctAnswer), questionNumber); } - } - - /** - * 生成高中题目 - */ - private Question generateSeniorQuestion(int questionNumber) { - // 使用常见角度: 0°, 30°, 45°, 60°, 90°, 120°, 135°, 150°, 180°, 210°, 225°, 270°, 300°, 315°, 330° - int[] commonAngles = {0, 30, 45, 60, 90, 120, 135, 150, 180, 210, 225, 270, 300, 315, 330}; - int angle = commonAngles[random.nextInt(commonAngles.length)]; - String[] functions = {"sin", "cos", "tan"}; - String function = functions[random.nextInt(functions.length)]; - - String questionText = String.format("%s(%d°) = ?", function, angle); - double result = calculateTrigFunction(function, angle); - - // 生成选项 - List options = generateTrigOptions(result); - // 使用格式化后的值作为正确答案,确保与选项一致 - String correctAnswer = formatTrigValue(result); - - // 随机打乱选项 - Collections.shuffle(options); - - return new Question(questionText, - options.get(0), - options.get(1), - options.get(2), - options.get(3), - correctAnswer, - questionNumber); } /** @@ -356,6 +404,246 @@ private double calculateTrigFunction(String function, int angle) { } + /** + * 生成复合运算表达式 + * @param operatorCount 运算符数量(1-3个) + * @return 返回[表达式字符串, 计算结果字符串] + */ + private String[] generateCompoundExpression(int operatorCount) { + StringBuilder expression = new StringBuilder(); + List operands = new ArrayList<>(); + List operators = new ArrayList<>(); + + // 生成操作数(运算符数量+1个操作数) + for (int i = 0; i <= operatorCount; i++) { + operands.add(MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE)); + } + + // 生成运算符 + String[] availableOps = {"+", "-", "*"}; + for (int i = 0; i < operatorCount; i++) { + operators.add(availableOps[random.nextInt(availableOps.length)]); + } + + // 构建表达式字符串 + expression.append(operands.get(0)); + for (int i = 0; i < operatorCount; i++) { + expression.append(" ").append(operators.get(i)).append(" ").append(operands.get(i + 1)); + } + expression.append(" = ?"); + + // 计算表达式结果 + int result = calculateCompoundExpression(operands, operators); + + return new String[]{expression.toString(), String.valueOf(result)}; + } + + /** + * 生成包含除法的复合运算表达式 + */ + private String[] generateCompoundExpressionWithDivision(int operatorCount) { + StringBuilder expression = new StringBuilder(); + List operands = new ArrayList<>(); + List operators = new ArrayList<>(); + + // 生成操作数(运算符数量+1个操作数) + for (int i = 0; i <= operatorCount; i++) { + operands.add(MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE)); + } + + // 生成运算符(包含除法) + String[] availableOps = {"+", "-", "*", "/"}; + for (int i = 0; i < operatorCount; i++) { + operators.add(availableOps[random.nextInt(availableOps.length)]); + } + + // 构建表达式字符串 + expression.append(operands.get(0)); + for (int i = 0; i < operatorCount; i++) { + expression.append(" ").append(operators.get(i)).append(" ").append(operands.get(i + 1)); + } + expression.append(" = ?"); + + // 计算表达式结果 + int result = calculateCompoundExpressionWithDivision(operands, operators); + + return new String[]{expression.toString(), String.valueOf(result)}; + } + + /** + * 计算复合表达式 + */ + private int calculateCompoundExpression(List operands, List operators) { + // 先处理乘除法,再处理加减法 + List numbers = new ArrayList<>(operands); + List ops = new ArrayList<>(operators); + + // 第一轮:处理乘除法 + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("*")) { + int result = numbers.get(i) * numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } + } + + // 第二轮:处理加减法 + int result = numbers.get(0); + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("+")) { + result += numbers.get(i + 1); + } else if (ops.get(i).equals("-")) { + result -= numbers.get(i + 1); + } + } + + return result; + } + + /** + * 生成高级复合运算表达式(包含平方运算) + */ + private String[] generateAdvancedCompoundExpression(int operatorCount) { + StringBuilder expression = new StringBuilder(); + List operands = new ArrayList<>(); + List operators = new ArrayList<>(); + + // 生成操作数(运算符数量+1个操作数) + for (int i = 0; i <= operatorCount; i++) { + operands.add(MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE)); + } + + // 生成运算符(包含平方运算) + String[] availableOps = {"+", "-", "*", "/", "²"}; + for (int i = 0; i < operatorCount; i++) { + operators.add(availableOps[random.nextInt(availableOps.length)]); + } + + // 构建表达式字符串 + expression.append(operands.get(0)); + for (int i = 0; i < operatorCount; i++) { + if (operators.get(i).equals("²")) { + expression.append("²"); + } else { + expression.append(" ").append(operators.get(i)).append(" ").append(operands.get(i + 1)); + } + } + expression.append(" = ?"); + + // 计算表达式结果 + int result = calculateAdvancedCompoundExpression(operands, operators); + + return new String[]{expression.toString(), String.valueOf(result)}; + } + + /** + * 计算包含除法的复合表达式 + */ + private int calculateCompoundExpressionWithDivision(List operands, List operators) { + // 先处理乘除法,再处理加减法 + List numbers = new ArrayList<>(operands); + List ops = new ArrayList<>(operators); + + // 第一轮:处理乘除法 + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("*")) { + int result = numbers.get(i) * numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } else if (ops.get(i).equals("/")) { + if (numbers.get(i + 1) != 0) { + int result = numbers.get(i) / numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } else { + // 避免除零错误,重新生成 + numbers.set(i + 1, 1 + random.nextInt(MAX_OPERAND_VALUE)); + int result = numbers.get(i) / numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } + } + } + + // 第二轮:处理加减法 + int result = numbers.get(0); + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("+")) { + result += numbers.get(i + 1); + } else if (ops.get(i).equals("-")) { + result -= numbers.get(i + 1); + } + } + + return result; + } + + /** + * 计算高级复合表达式(包含平方运算) + */ + private int calculateAdvancedCompoundExpression(List operands, List operators) { + // 先处理平方运算 + List numbers = new ArrayList<>(operands); + List ops = new ArrayList<>(operators); + + // 第一轮:处理平方运算 + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("²")) { + int result = numbers.get(i) * numbers.get(i); + numbers.set(i, result); + ops.remove(i); + i--; // 调整索引 + } + } + + // 第二轮:处理乘除法 + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("*")) { + int result = numbers.get(i) * numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } else if (ops.get(i).equals("/")) { + if (numbers.get(i + 1) != 0) { + int result = numbers.get(i) / numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } else { + // 避免除零错误,重新生成 + numbers.set(i + 1, 1 + random.nextInt(MAX_OPERAND_VALUE)); + int result = numbers.get(i) / numbers.get(i + 1); + numbers.set(i, result); + numbers.remove(i + 1); + ops.remove(i); + i--; // 调整索引 + } + } + } + + // 第三轮:处理加减法 + int result = numbers.get(0); + for (int i = 0; i < ops.size(); i++) { + if (ops.get(i).equals("+")) { + result += numbers.get(i + 1); + } else if (ops.get(i).equals("-")) { + result -= numbers.get(i + 1); + } + } + + return result; + } + /** * 获取随机运算符 */ diff --git a/user_data.txt b/user_data.txt index cc12efd..8402612 100644 --- a/user_data.txt +++ b/user_data.txt @@ -1,2 +1,2 @@ -wgll|123456|ymhlovesLQX@163.com|小学|1760162416490 +wgll|Ymh123456|ymhlovesLQX@163.com|小学|1760162416490 666|123456789|252436951@qq.com|小学|1760166999971