sqf_branch
宋奇峰 2 months ago
parent 7b468e720c
commit d31cb6fd5a

Binary file not shown.

@ -22,8 +22,8 @@ src/
├─ ExamFrame.java ├─ ExamFrame.java
└─ ResultFrame.java └─ ResultFrame.java
lib/ lib/
├─ Main.java ├─ jakarta.activation-2.0.1.jar
└─ view/ └─ jakarta.mail-2.0.1.jar
--- ---

@ -13,105 +13,82 @@ import javax.script.ScriptException;
*/ */
public class Create { public class Create {
// 评估表达式数值double若失败抛异常
private static double evalExpression(String expr) throws ScriptException { private static double evalExpression(String expr) throws ScriptException {
return ExpressionEvaluator.evaluate(expr); return ExpressionEvaluator.evaluate(expr);
} }
/**
* Paper questions, options, correctIndex
*/
public static Paper create(int n, Login.Level currentLevel, Login.Account user) { public static Paper create(int n, Login.Level currentLevel, Login.Account user) {
List<String> existing = LoadFile.loadExistingQuestions(user.username); List<String> existing = LoadFile.loadExistingQuestions(user.username);
Generator qg = new Generator(currentLevel, existing); List<String> paper = generatePaper(n, currentLevel, existing);
List<String> paper = qg.generatePaper(n); if (paper.isEmpty()) return null;
if (paper.isEmpty()) {
return null;
}
// 为每道题生成 4 个选项:一个正确值(三位有效数)加上 3 个干扰项
List<String[]> optionsList = new ArrayList<>(); List<String[]> optionsList = new ArrayList<>();
int[] correctIdx = new int[paper.size()]; int[] correctIdx = new int[paper.size()];
for (int i = 0; i < paper.size(); i++) { for (int i = 0; i < paper.size(); i++) {
String q = paper.get(i); String q = paper.get(i);
double correctVal; optionsList.add(generateOptions(q, correctIdx, i));
try { }
correctVal = evalExpression(q);
} catch (Exception ex) { savePaper(user.username, paper);
// 如果无法精确计算(如复杂表达式),我们退而使用字符串匹配:将题目文本作为正确选项,生成三个变体文本
String[] opts = new String[4]; return new Paper(paper, optionsList, correctIdx);
opts[0] = q; }
opts[1] = q + " + 1";
opts[2] = q + " - 1"; private static List<String> generatePaper(int n, Login.Level level, List<String> existing) {
opts[3] = "错误:" + q; Generator qg = new Generator(level, existing);
shuffleArray(opts); return qg.generatePaper(n);
int idx = findIndex(opts, q); }
optionsList.add(opts);
correctIdx[i] = idx; private static String[] generateOptions(String question, int[] correctIdx, int i) {
continue; double correctVal;
} try {
correctVal = evalExpression(question);
// 格式化正确值为保留3位小数若为整数则不显示小数 return generateNumericOptions(correctVal, correctIdx, i);
String correctStr = formatNumber(correctVal); } catch (Exception e) {
return generateTextOptions(question, correctIdx, i);
// 判断是否为整数答案 }
boolean isIntAnswer = Math.abs(correctVal - Math.round(correctVal)) < 1e-6; }
// 产生三个干扰值
Set<String> optsSet = new LinkedHashSet<>();
optsSet.add(correctStr);
Random r = new Random();
int attempts = 0;
while (optsSet.size() < 4 && attempts < 50) {
attempts++;
double delta;
if (isIntAnswer) {
// 整数题:干扰项也是整数(偏差 ±1~±10
delta = r.nextInt(10) + 1;
if (r.nextBoolean()) {
delta = -delta;
}
} else {
// 小数题:随机偏差比例
delta = (Math.abs(correctVal) < 1e-6)
? (r.nextDouble() * 5 + 1)
: (r.nextGaussian() * Math.max(1, Math.abs(correctVal) * 0.15));
}
double cand = correctVal + delta;
String s = formatNumber(cand);
optsSet.add(s);
}
// 不足 4 个时补齐
while (optsSet.size() < 4) {
double cand = isIntAnswer
? correctVal + (r.nextInt(10) - 5)
: correctVal + (r.nextDouble() * 2 - 1);
optsSet.add(formatNumber(cand));
}
String[] optsArr = optsSet.toArray(new String[0]);
// 随机打乱并记录正确项位置
shuffleArray(optsArr);
int idx = findIndex(optsArr, correctStr);
optionsList.add(optsArr);
correctIdx[i] = idx;
private static String[] generateTextOptions(String question, int[] correctIdx, int i) {
String[] opts = new String[]{question, question + " + 1", question + " - 1", "错误:" + question};
shuffleArray(opts);
correctIdx[i] = findIndex(opts, question);
return opts;
}
private static String[] generateNumericOptions(double correctVal, int[] correctIdx, int i) {
String correctStr = formatNumber(correctVal);
boolean isInt = Math.abs(correctVal - Math.round(correctVal)) < 1e-6;
Set<String> optsSet = new LinkedHashSet<>();
optsSet.add(correctStr);
Random r = new Random();
int attempts = 0;
while (optsSet.size() < 4 && attempts < 50) {
attempts++;
double delta = isInt ? r.nextInt(10) + 1 : (r.nextGaussian() * Math.max(1, Math.abs(correctVal) * 0.15));
if (isInt && r.nextBoolean()) delta = -delta;
optsSet.add(formatNumber(correctVal + delta));
} }
// 保存试卷原文本(题干)到文件(按你的 Save 实现) while (optsSet.size() < 4) {
double delta = isInt ? r.nextInt(10) - 5 : r.nextDouble() * 2 - 1;
optsSet.add(formatNumber(correctVal + delta));
}
String[] optsArr = optsSet.toArray(new String[0]);
shuffleArray(optsArr);
correctIdx[i] = findIndex(optsArr, correctStr);
return optsArr;
}
private static void savePaper(String username, List<String> paper) {
try { try {
// 为保存,我们保存原题干列表(文本) Save.savePaper(username, new ArrayList<>(paper));
java.util.List<String> raw = new ArrayList<>();
for (String s : paper) {
raw.add(s);
}
Save.savePaper(user.username, raw);
} catch (RuntimeException re) { } catch (RuntimeException re) {
// 抛给 UI 处理(但仍返回 Paper
System.err.println("保存试卷时出错: " + re.getMessage()); System.err.println("保存试卷时出错: " + re.getMessage());
} }
return new Paper(paper, optionsList, correctIdx);
} }
private static void shuffleArray(String[] arr) { private static void shuffleArray(String[] arr) {
@ -125,19 +102,13 @@ public class Create {
} }
private static int findIndex(String[] arr, String target) { private static int findIndex(String[] arr, String target) {
for (int i = 0; i < arr.length; i++) { for (int i = 0; i < arr.length; i++) if (arr[i].equals(target)) return i;
if (arr[i].equals(target)) {
return i;
}
}
return 0; return 0;
} }
private static String formatNumber(double v) { private static String formatNumber(double v) {
if (Math.abs(v - Math.round(v)) < 1e-6) { if (Math.abs(v - Math.round(v)) < 1e-6) return String.valueOf((long) Math.round(v));
return String.valueOf((long) Math.round(v)); return String.format("%.3f", v);
} else {
return String.format("%.3f", v);
}
} }
} }

Loading…
Cancel
Save