modify files
This commit is contained in:
112
AIGrammar/Models/PuzzleGenerator.swift
Normal file
112
AIGrammar/Models/PuzzleGenerator.swift
Normal file
@ -0,0 +1,112 @@
|
||||
//
|
||||
// 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())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user