Files
QuizApp/QuizApp/ViewModels/ViewModel.swift

117 lines
3.4 KiB
Swift

//
// ViewModel.swift
// QuizApp
//
// Created by Paul on 03.08.25.
//
import Foundation
class ViewModel: ObservableObject {
private var allQuestionsByCategory: [String: [QuizQuestion]] = [:]
@Published var questions: [QuizQuestion] = []
@Published var selectedCategory: String? = nil
@Published var currentQuestionIndex: Int = 0
@Published var score: Int = 0
@Published var isQuizFinished: Bool = false
@Published var answeredCount: Int = 0
@Published var selectedAnswers: [Int?] = []
var progress: Double {
guard !questions.isEmpty else { return 0.0 }
return Double(answeredCount) / Double(questions.count)
}
var currentQuestion: QuizQuestion? {
guard currentQuestionIndex < questions.count else { return nil }
return questions[currentQuestionIndex]
}
var availableCategories: [String] {
return Array(allQuestionsByCategory.keys).sorted()
}
init() {
guard let url = Bundle.main.url(forResource: "questions", withExtension: "json") else {
questions = []
return
}
do {
let data = try Data(contentsOf: url)
allQuestionsByCategory = try JSONDecoder().decode([String: [QuizQuestion]].self, from: data)
print("Fragen geladen")
} catch {
print("Fehler beim Laden des Inhalts: \(error)")
allQuestionsByCategory = [:]
}
}
func loadNextQuestion() {
if currentQuestionIndex + 1 < questions.count {
currentQuestionIndex += 1
} else {
isQuizFinished = true
}
}
func loadQuestions(for category: String) {
selectedCategory = category
questions = allQuestionsByCategory[category] ?? []
currentQuestionIndex = 0
score = 0
isQuizFinished = false
answeredCount = 0
selectedAnswers = Array(repeating: nil, count: questions.count)
print(selectedAnswers)
}
func incrementScore(selectedIndex: Int) {
if let correct = currentQuestion?.correctAnswer, selectedIndex == correct {
score += 1
}
}
func pointsForEstimation(
guess: Double,
correct: Double,
maxPoints: Int = 1,
) -> Int {
let absError = abs(guess - correct) // Absolute Abweichung
let relError = absError / abs(correct) // Relative Abweichung
if relError <= 0.1 {
return maxPoints
} else {
return 0
}
}
func highscore(for category: String) -> Int {
let dict = UserDefaults.standard.dictionary(forKey: "categoryHighscores") as? [String: Int] ?? [:]
return dict[category] ?? 0
}
@discardableResult
func updateHighscoreIfNeeded() -> Bool {
guard let category = selectedCategory else { return false }
var dict = UserDefaults.standard.dictionary(forKey: "categoryHighscores") as? [String: Int] ?? [:]
let oldScore = dict[category] ?? 0
if score > oldScore {
dict[category] = score
UserDefaults.standard.set(dict, forKey: "categoryHighscores")
return true
}
return false
}
func allHighscores() -> [String: Int] {
UserDefaults.standard.dictionary(forKey: "categoryHighscores") as? [String: Int] ?? [:]
}
}