You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
7.7 KiB
225 lines
7.7 KiB
package com.mathlearning.controller;
|
|
|
|
import com.mathlearning.model.*;
|
|
import com.mathlearning.util.ExamFileUtil;
|
|
|
|
import java.util.*;
|
|
|
|
public class ExamController {
|
|
private Paper currentPaper;
|
|
private String currentUser;
|
|
private String currentLevel;
|
|
|
|
public ExamController() {
|
|
}
|
|
|
|
public void createExam(String level, int questionCount) {
|
|
System.out.println("=== 开始创建试卷 ===");
|
|
System.out.println("级别: " + level + ", 题目数量: " + questionCount);
|
|
|
|
long startTime = System.currentTimeMillis();
|
|
this.currentLevel = level;
|
|
|
|
try {
|
|
QuestionGenerator generator = QuestionGenerator.createGenerator(level);
|
|
System.out.println("生成器创建完成: " + generator.getClass().getSimpleName());
|
|
|
|
List<Question> questions = generateQuestionsWithTimeout(generator, questionCount, 15000); // 15秒超时
|
|
|
|
System.out.println("题目生成完成,生成了 " + questions.size() + " 道题目");
|
|
|
|
int duplicateCount = checkForDuplicates(questions);
|
|
if (duplicateCount > 0) {
|
|
System.out.println("警告: 发现 " + duplicateCount + " 道重复题目");
|
|
}
|
|
|
|
currentPaper = new Paper(level);
|
|
for (Question question : questions) {
|
|
currentPaper.addQuestion(question);
|
|
}
|
|
|
|
long endTime = System.currentTimeMillis();
|
|
System.out.println("试卷创建完成,耗时: " + (endTime - startTime) + "ms");
|
|
System.out.println("=== 试卷创建结束 ===");
|
|
|
|
} catch (Exception e) {
|
|
System.err.println("创建试卷时发生错误: " + e.getMessage());
|
|
e.printStackTrace();
|
|
currentPaper = new Paper(level);
|
|
List<Question> basicQuestions = generateBasicQuestions(questionCount);
|
|
for (Question question : basicQuestions) {
|
|
currentPaper.addQuestion(question);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private List<Question> generateQuestionsWithTimeout(QuestionGenerator generator, int count, long timeoutMs) {
|
|
long startTime = System.currentTimeMillis();
|
|
List<Question> questions = new ArrayList<>();
|
|
|
|
try {
|
|
List<Question> generated = generator.generateQuestions(count);
|
|
questions.addAll(generated);
|
|
|
|
if ((System.currentTimeMillis() - startTime) > timeoutMs) {
|
|
System.out.println("生成题目超时,使用已生成的部分题目");
|
|
}
|
|
|
|
if (questions.size() > count) {
|
|
questions = questions.subList(0, count);
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
System.err.println("生成题目时出错: " + e.getMessage());
|
|
}
|
|
|
|
if (questions.size() < count) {
|
|
System.out.println("题目数量不足,补充基础题目...");
|
|
int needed = count - questions.size();
|
|
List<Question> basicQuestions = generateBasicQuestions(needed);
|
|
questions.addAll(basicQuestions);
|
|
}
|
|
|
|
return questions;
|
|
}
|
|
|
|
|
|
private List<Question> generateBasicQuestions(int count) {
|
|
System.out.println("生成 " + count + " 道基础题目");
|
|
List<Question> basicQuestions = new ArrayList<>();
|
|
Random random = new Random();
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
int a = random.nextInt(10) + 1;
|
|
int b = random.nextInt(10) + 1;
|
|
int operation = random.nextInt(2); // 0: 加法, 1: 减法
|
|
|
|
String expression;
|
|
int answer;
|
|
|
|
if (operation == 0) {
|
|
expression = a + " + " + b;
|
|
answer = a + b;
|
|
} else {
|
|
if (a < b) {
|
|
int temp = a;
|
|
a = b;
|
|
b = temp;
|
|
}
|
|
expression = a + " - " + b;
|
|
answer = a - b;
|
|
}
|
|
|
|
Set<String> options = new HashSet<>();
|
|
options.add(String.valueOf(answer));
|
|
|
|
while (options.size() < 4) {
|
|
int variation = random.nextInt(5) + 1;
|
|
int wrongAnswer;
|
|
if (random.nextBoolean()) {
|
|
wrongAnswer = answer + variation;
|
|
} else {
|
|
wrongAnswer = Math.max(1, answer - variation);
|
|
}
|
|
options.add(String.valueOf(wrongAnswer));
|
|
}
|
|
|
|
List<String> optionList = new ArrayList<>(options);
|
|
Collections.shuffle(optionList);
|
|
String optionsStr = String.join(",", optionList);
|
|
|
|
basicQuestions.add(new Question(expression + " = ?", optionsStr, String.valueOf(answer)));
|
|
}
|
|
|
|
return basicQuestions;
|
|
}
|
|
|
|
|
|
public boolean saveCurrentPaper() {
|
|
if (currentPaper == null || currentUser == null) {
|
|
System.err.println("无法保存试卷: 试卷或用户信息为空");
|
|
return false;
|
|
}
|
|
|
|
return ExamFileUtil.savePaperToFile(currentUser, currentPaper);
|
|
}
|
|
|
|
private int checkForDuplicates(List<Question> questions) {
|
|
Set<String> expressions = new HashSet<>();
|
|
int duplicateCount = 0;
|
|
|
|
for (Question question : questions) {
|
|
String expression = extractExpression(question.getContent());
|
|
if (expressions.contains(expression)) {
|
|
duplicateCount++;
|
|
System.out.println("发现重复题目: " + question.getContent());
|
|
} else {
|
|
expressions.add(expression);
|
|
}
|
|
}
|
|
|
|
return duplicateCount;
|
|
}
|
|
|
|
private String extractExpression(String content) {
|
|
if (content == null) return "";
|
|
return content.replace(" = ?", "").trim();
|
|
}
|
|
|
|
public Question getCurrentQuestion() {
|
|
return currentPaper != null ? currentPaper.getCurrentQuestion() : null;
|
|
}
|
|
|
|
public boolean hasNextQuestion() {
|
|
return currentPaper != null && currentPaper.hasNextQuestion();
|
|
}
|
|
|
|
public void nextQuestion() {
|
|
if (currentPaper != null) {
|
|
currentPaper.nextQuestion();
|
|
}
|
|
}
|
|
|
|
public boolean hasPreviousQuestion() {
|
|
return currentPaper != null && currentPaper.hasPreviousQuestion();
|
|
}
|
|
|
|
public void previousQuestion() {
|
|
if (currentPaper != null) {
|
|
currentPaper.previousQuestion();
|
|
}
|
|
}
|
|
|
|
public void submitAnswer(String answer) {
|
|
Question currentQuestion = getCurrentQuestion();
|
|
if (currentQuestion != null) {
|
|
currentQuestion.setUserAnswer(answer);
|
|
System.out.println("题目 " + getCurrentQuestionNumber() + " 答案设置为: " + answer);
|
|
}
|
|
}
|
|
|
|
public int calculateScore() {
|
|
return currentPaper != null ? currentPaper.calculateScore() : 0;
|
|
}
|
|
|
|
public int getCurrentQuestionNumber() {
|
|
return currentPaper != null ? currentPaper.getCurrentQuestionNumber() : 0;
|
|
}
|
|
|
|
public int getTotalQuestions() {
|
|
return currentPaper != null ? currentPaper.getTotalQuestions() : 0;
|
|
}
|
|
|
|
public String getCurrentLevel() {
|
|
return currentLevel;
|
|
}
|
|
|
|
public void setCurrentUser(String user) {
|
|
this.currentUser = user;
|
|
}
|
|
|
|
public Paper getCurrentPaper() {
|
|
return currentPaper;
|
|
}
|
|
} |