113 lines
3.8 KiB
Swift
113 lines
3.8 KiB
Swift
//
|
|
// PuzzleGenerator.swift
|
|
// AIGrammar
|
|
//
|
|
// Created by oscar on 2025/7/21.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
|
|
class PuzzleGenerator {
|
|
private(set) var validationWords: Set<String> = []
|
|
private(set) var puzzleWords: [String] = []
|
|
|
|
init() {
|
|
//loadValidationWords()
|
|
//loadPuzzleWords()
|
|
validationWords = Set(loadWords(from: "wordlist"))
|
|
puzzleWords = loadWords(from: "puzzle")
|
|
}
|
|
|
|
/// 通用加载逻辑
|
|
private func loadWords(from fileName: String) -> [String] {
|
|
if let url = Bundle.main.url(forResource: fileName, withExtension: "txt") {
|
|
do {
|
|
let content = try String(contentsOf: url)
|
|
let words = content
|
|
.components(separatedBy: .newlines)
|
|
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() }
|
|
.filter { !$0.isEmpty }
|
|
logger.info("Loaded \(words.count) words from \(fileName).txt")
|
|
return words
|
|
} catch {
|
|
logger.warning("Failed to load \(fileName).txt: \(error)")
|
|
}
|
|
} else {
|
|
logger.warning("\(fileName).txt not found!")
|
|
}
|
|
return []
|
|
}
|
|
|
|
/// 加载验证单词库
|
|
private func loadValidationWords() {
|
|
if let url = Bundle.main.url(forResource: "wordlist", withExtension: "txt") {
|
|
do {
|
|
let content = try String(contentsOf: url)
|
|
validationWords = Set(content
|
|
.components(separatedBy: .newlines)
|
|
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() }
|
|
.filter { !$0.isEmpty })
|
|
logger.info("Loaded validation words: \(validationWords.count)")
|
|
} catch {
|
|
logger.warning("Failed to load wordlist.txt: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 加载出题单词库
|
|
private func loadPuzzleWords() {
|
|
if let url = Bundle.main.url(forResource: "puzzle", withExtension: "txt") {
|
|
do {
|
|
let content = try String(contentsOf: url)
|
|
puzzleWords = content
|
|
.components(separatedBy: .newlines)
|
|
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() }
|
|
.filter { !$0.isEmpty }
|
|
logger.info("Loaded puzzle words: \(puzzleWords.count)")
|
|
} catch {
|
|
logger.warning("Failed to load puzzle.txt: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 随机生成一套题目
|
|
func generatePuzzle() -> (Set<String>, [[String]]) {
|
|
var chosenWords: Set<String> = []
|
|
var uniqueLetters: Set<Character> = []
|
|
|
|
while (uniqueLetters.count < 16 && chosenWords.count < 6) || chosenWords.count < 4 {
|
|
if let word = puzzleWords.randomElement() {
|
|
chosenWords.insert(word)
|
|
uniqueLetters.formUnion(word)
|
|
}
|
|
}
|
|
|
|
// 保证16个不同字母
|
|
var selectedLetters = Array(uniqueLetters)
|
|
let alphabet = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
while selectedLetters.count < 16 {
|
|
let randomLetter = alphabet.randomElement()!
|
|
if !selectedLetters.contains(randomLetter) {
|
|
selectedLetters.append(randomLetter)
|
|
}
|
|
}
|
|
|
|
let shuffledLetters = selectedLetters.shuffled()
|
|
|
|
var letters: [[String]] = Array(repeating: Array(repeating: "", count: 4), count: 4)
|
|
for i in 0..<4 {
|
|
for j in 0..<4 {
|
|
letters[i][j] = String(shuffledLetters[i * 4 + j])
|
|
}
|
|
}
|
|
|
|
return (chosenWords, letters)
|
|
}
|
|
|
|
/// 校验用户提交的单词
|
|
func validate(word: String) -> Bool {
|
|
validationWords.contains(word.uppercased())
|
|
}
|
|
}
|