@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.scapeSharing</groupId>
|
||||
<artifactId>Quiz_Generator_personal</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.30</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
package com.quizgenerator.common;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/** 三种习题等级. */
|
||||
@Getter
|
||||
public enum Level {
|
||||
PRIMARY("小学"),
|
||||
JUNIOR_HIGH("初中"),
|
||||
SENIOR_HIGH("高中");
|
||||
|
||||
private final String displayName;
|
||||
|
||||
Level(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取等级.
|
||||
*
|
||||
* @param text s
|
||||
* @return Level
|
||||
*/
|
||||
public static Level fromString(String text) {
|
||||
for (Level b : Level.values()) {
|
||||
if (b.displayName.equalsIgnoreCase(text)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.quizgenerator.common;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/** 一个用于题目生成的辅助工具类. 包含所有生成器可能共享的静态方法。 */
|
||||
public final class QuestionUtils {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private QuestionUtils() {}
|
||||
|
||||
/**
|
||||
* 检查一个字符串是否可以被解析为整数.
|
||||
*
|
||||
* @param str 要检查的字符串
|
||||
* @return 如果是数字则为 true, 否则为 false
|
||||
*/
|
||||
public static boolean isNotNumeric(String str) {
|
||||
if (str == null) {
|
||||
return true; // null 不是数字,所以返回 true
|
||||
}
|
||||
|
||||
try {
|
||||
Integer.parseInt(str);
|
||||
return false; // 能成功转换,说明是数字,所以返回 false
|
||||
} catch (NumberFormatException e) {
|
||||
return true; // 转换失败,说明不是数字,所以返回 true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回一个随机的四则运算符 (+, -, *, /).
|
||||
*
|
||||
* @return 随机的运算符字符
|
||||
*/
|
||||
public static char getRandomOperator() {
|
||||
char[] operators = {'+', '-', '*', '/'};
|
||||
return operators[RANDOM.nextInt(operators.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回一个1到100之间的随机操作数.
|
||||
*
|
||||
* @return 随机整数
|
||||
*/
|
||||
public static int getRandomOperand() {
|
||||
return RANDOM.nextInt(100) + 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.quizgenerator.entity;
|
||||
|
||||
import com.quizgenerator.common.Level;
|
||||
import lombok.Data;
|
||||
|
||||
/** User类. */
|
||||
@Data
|
||||
public class User {
|
||||
private final String username;
|
||||
private final String password;
|
||||
private final Level level;
|
||||
|
||||
/*public User(String username, String password, Level level) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public Level getLevel() {
|
||||
return level;
|
||||
}*/
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.quizgenerator.generator;
|
||||
|
||||
/** 题目生成接口. */
|
||||
public interface QuestionGenerator {
|
||||
|
||||
/**
|
||||
* 核心方法.
|
||||
*
|
||||
* @return 生成的题目字符串
|
||||
*/
|
||||
String generate();
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.quizgenerator.generator.impl;
|
||||
|
||||
import com.quizgenerator.common.QuestionUtils;
|
||||
import com.quizgenerator.generator.QuestionGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
/** 初中题目生成. */
|
||||
public class JuniorHighGenerator implements QuestionGenerator {
|
||||
private final Random random = new Random();
|
||||
private final QuestionGenerator primaryGenerator = new PrimarySchoolGenerator();
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
// 1.复用primary逻辑
|
||||
// 可以优化,抽出复用逻辑,不应该让同层的类互相依赖
|
||||
String baseQuestion = primaryGenerator.generate();
|
||||
String[] parts = baseQuestion.split(" ");
|
||||
|
||||
int indexToModify;
|
||||
do {
|
||||
indexToModify = random.nextInt(parts.length);
|
||||
} while (QuestionUtils.isNotNumeric(parts[indexToModify]));
|
||||
|
||||
if (random.nextBoolean()) {
|
||||
parts[indexToModify] = parts[indexToModify] + "^2";
|
||||
} else {
|
||||
parts[indexToModify] = "sqrt(" + parts[indexToModify] + ")";
|
||||
}
|
||||
|
||||
return String.join(" ", parts);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.quizgenerator.generator.impl;
|
||||
|
||||
import com.quizgenerator.common.QuestionUtils;
|
||||
import com.quizgenerator.generator.QuestionGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
/** 小学题目生成. */
|
||||
public class PrimarySchoolGenerator implements QuestionGenerator {
|
||||
private final Random random = new Random();
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
int operandCount = random.nextInt(4) + 2;
|
||||
StringBuilder question = new StringBuilder();
|
||||
question.append(QuestionUtils.getRandomOperand());
|
||||
|
||||
for (int i = 0; i < operandCount - 1; i++) {
|
||||
question.append(" ").append(QuestionUtils.getRandomOperator()).append(" ");
|
||||
|
||||
if (random.nextBoolean() && i < operandCount - 2) {
|
||||
question.append("( ").append(QuestionUtils.getRandomOperand()).append(" ");
|
||||
question.append(QuestionUtils.getRandomOperator()).append(" ");
|
||||
question.append(QuestionUtils.getRandomOperand()).append(" )");
|
||||
i++;
|
||||
} else {
|
||||
question.append(QuestionUtils.getRandomOperand());
|
||||
}
|
||||
}
|
||||
return question.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.quizgenerator.generator.impl;
|
||||
|
||||
import com.quizgenerator.common.QuestionUtils;
|
||||
import com.quizgenerator.generator.QuestionGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
/** 高中题目生成 */
|
||||
public class SeniorHighGenerator implements QuestionGenerator {
|
||||
private final Random random = new Random();
|
||||
private final QuestionGenerator primaryGenerator = new PrimarySchoolGenerator();
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
String baseQuestion = primaryGenerator.generate();
|
||||
String[] parts = baseQuestion.split(" ");
|
||||
|
||||
int indexToModify;
|
||||
do {
|
||||
indexToModify = random.nextInt(parts.length);
|
||||
} while (QuestionUtils.isNotNumeric(parts[indexToModify]));
|
||||
|
||||
String[] trigFuncs = {"sin", "cos", "tan"};
|
||||
String func = trigFuncs[random.nextInt(trigFuncs.length)];
|
||||
|
||||
int[] angles = {30, 45, 60, 90};
|
||||
int angle = angles[random.nextInt(angles.length)];
|
||||
|
||||
parts[indexToModify] = func + "(" + angle + ")";
|
||||
|
||||
return String.join(" ", parts);
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package com.quizgenerator.service;
|
||||
|
||||
import com.quizgenerator.common.Level;
|
||||
import com.quizgenerator.generator.QuestionGenerator;
|
||||
import com.quizgenerator.generator.impl.JuniorHighGenerator;
|
||||
import com.quizgenerator.generator.impl.PrimarySchoolGenerator;
|
||||
import com.quizgenerator.generator.impl.SeniorHighGenerator;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/** 问题核心处理逻辑. */
|
||||
public class QuestionService {
|
||||
private final Map<Level, QuestionGenerator> generators = new HashMap<>();
|
||||
|
||||
/** 构造函数,初始化题目生成器. */
|
||||
public QuestionService() {
|
||||
generators.put(Level.PRIMARY, new PrimarySchoolGenerator());
|
||||
generators.put(Level.JUNIOR_HIGH, new JuniorHighGenerator());
|
||||
generators.put(Level.SENIOR_HIGH, new SeniorHighGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定数量的不重复题目.
|
||||
*
|
||||
* @param level 题目等级
|
||||
* @param count 题目数量
|
||||
* @param username 用户名
|
||||
* @return 包含不重复题目的列表
|
||||
*/
|
||||
public List<String> generateUniqueQuiz(Level level, int count, String username) {
|
||||
QuestionGenerator generator = generators.get(level);
|
||||
if (generator == null) {
|
||||
throw new IllegalArgumentException("无效的等级代号");
|
||||
}
|
||||
|
||||
Set<String> existingQuestions = loadExistingQuestions(username);
|
||||
List<String> newQuestions = new ArrayList<>();
|
||||
|
||||
while (newQuestions.size() < count) {
|
||||
String question = generator.generate();
|
||||
if (!existingQuestions.contains(question)) {
|
||||
newQuestions.add(question);
|
||||
existingQuestions.add(question);
|
||||
}
|
||||
}
|
||||
return newQuestions;
|
||||
}
|
||||
|
||||
private Set<String> loadExistingQuestions(String username) {
|
||||
Set<String> questions = new HashSet<>();
|
||||
File userDir = new File(username);
|
||||
if (!userDir.exists() || !userDir.isDirectory()) {
|
||||
return questions;
|
||||
}
|
||||
|
||||
try (Stream<Path> paths = Files.walk(Paths.get(username))) {
|
||||
paths
|
||||
.filter(Files::isRegularFile)
|
||||
.filter(path -> path.toString().endsWith(".txt"))
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
Files.lines(path)
|
||||
.forEach(
|
||||
line -> {
|
||||
// Extract question text, assuming format "1. question..."
|
||||
if (line.matches("^\\d+\\.\\s.*")) {
|
||||
questions.add(line.substring(line.indexOf('.') + 2));
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading file: " + path);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error walking directory: " + username);
|
||||
}
|
||||
return questions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存到文件.
|
||||
*
|
||||
* @param questions 问题
|
||||
* @param username 用户
|
||||
*/
|
||||
public void saveQuizToFile(List<String> questions, String username) {
|
||||
File userDir = new File(username);
|
||||
if (!userDir.exists()) {
|
||||
userDir.mkdirs(); // Create directory if it doesn't exist
|
||||
}
|
||||
|
||||
String timestamp =
|
||||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"));
|
||||
String filename = username + "/" + timestamp + ".txt";
|
||||
|
||||
try (FileWriter writer = new FileWriter(filename)) {
|
||||
for (int i = 0; i < questions.size(); i++) {
|
||||
writer.write((i + 1) + ". " + questions.get(i) + "\n");
|
||||
writer.write("\n"); // Blank line between questions
|
||||
}
|
||||
System.out.println("试卷已成功生成并保存至: " + filename);
|
||||
} catch (IOException e) {
|
||||
System.err.println("错误:无法保存文件 " + filename);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.quizgenerator.system;
|
||||
|
||||
import com.quizgenerator.entity.User;
|
||||
import com.quizgenerator.service.QuestionService;
|
||||
import com.quizgenerator.service.UserService;
|
||||
|
||||
/** 应用程序的主入口类,负责启动和协调整个问答流程. */
|
||||
public class QuizApplication {
|
||||
private final LoginHandler loginHandler;
|
||||
private final MainMenuHandler mainMenuHandler;
|
||||
private final ConsoleUi consoleUi;
|
||||
|
||||
/** 构造 QuizApplication 实例. 负责初始化所有必要的服务和处理器. */
|
||||
public QuizApplication() {
|
||||
// 1. 初始化
|
||||
UserService userService = new UserService();
|
||||
QuestionService questionService = new QuestionService();
|
||||
this.consoleUi = new ConsoleUi();
|
||||
|
||||
// 2. 初始化处理器
|
||||
this.loginHandler = new LoginHandler(userService, consoleUi);
|
||||
this.mainMenuHandler = new MainMenuHandler(questionService, consoleUi);
|
||||
}
|
||||
|
||||
/** 启动并运行应用程序的主循环. 这个方法会持续运行,处理用户登录和主菜单交互. */
|
||||
public void run() {
|
||||
consoleUi.displayWelcomeMessage();
|
||||
while (true) {
|
||||
// 3. 处理登录流程
|
||||
User currentUser = loginHandler.performLogin();
|
||||
|
||||
// 4. 进入主菜单循环
|
||||
if (currentUser != null) {
|
||||
consoleUi.displayLoginSuccess(currentUser);
|
||||
mainMenuHandler.handleMainMenu(currentUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用程序的入口点.
|
||||
*
|
||||
* @param args 命令行参数 (未使用).
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
QuizApplication app = new QuizApplication();
|
||||
app.run();
|
||||
}
|
||||
}
|
Loading…
Reference in new issue