fix: some restructuring
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Topic.swift
|
||||
// QuizQuestion.swift
|
||||
// QuizApp
|
||||
//
|
||||
// Created by Paul on 03.08.25.
|
||||
|
||||
@@ -66,6 +66,7 @@ class ViewModel: ObservableObject {
|
||||
isQuizFinished = false
|
||||
answeredCount = 0
|
||||
selectedAnswers = Array(repeating: nil, count: questions.count)
|
||||
print(selectedAnswers)
|
||||
}
|
||||
|
||||
|
||||
@@ -74,4 +75,24 @@ class ViewModel: ObservableObject {
|
||||
score += 1
|
||||
}
|
||||
}
|
||||
|
||||
func pointsForEstimation(
|
||||
guess: Double,
|
||||
correct: Double,
|
||||
minValue: Double,
|
||||
maxValue: Double,
|
||||
maxPoints: Int = 3,
|
||||
thresholdPercent: Double = 0.3
|
||||
) -> Int {
|
||||
let span = maxValue - minValue
|
||||
guard span > 0 else { return 0 }
|
||||
|
||||
let absError = abs(guess - correct)
|
||||
let relError = absError / span
|
||||
|
||||
if relError >= thresholdPercent { return 0 }
|
||||
|
||||
let ratio = 1.0 - (relError / thresholdPercent)
|
||||
return max(0, Int(round(Double(maxPoints) * ratio)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,36 +72,33 @@ struct CategorySelectionView: View {
|
||||
// Liste der Kategorien
|
||||
VStack(spacing: 12) {
|
||||
ForEach(viewModel.availableCategories, id: \.self) { category in
|
||||
NavigationLink(destination: ContentView(viewModel: viewModel)
|
||||
.onAppear {
|
||||
viewModel.loadQuestions(for: category)
|
||||
}) {
|
||||
HStack {
|
||||
Image(systemName: "play.circle.fill")
|
||||
.foregroundColor(.blue)
|
||||
.font(.title2)
|
||||
NavigationLink(destination: ContentView(viewModel: viewModel, category: category)) {
|
||||
HStack {
|
||||
Image(systemName: "play.circle.fill")
|
||||
.foregroundColor(.blue)
|
||||
.font(.title2)
|
||||
|
||||
Text(category)
|
||||
.font(.headline)
|
||||
.foregroundColor(.primary)
|
||||
Text(category)
|
||||
.font(.headline)
|
||||
.foregroundColor(.primary)
|
||||
|
||||
Spacer()
|
||||
Spacer()
|
||||
|
||||
Image(systemName: "chevron.right")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption)
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color(.systemGray6))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.stroke(Color(.systemGray4), lineWidth: 1)
|
||||
)
|
||||
)
|
||||
Image(systemName: "chevron.right")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color(.systemGray6))
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.stroke(Color(.systemGray4), lineWidth: 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
@@ -161,3 +158,7 @@ struct CategorySelectionView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
CategorySelectionView()
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ struct ContentView: View {
|
||||
@AppStorage("globalScore") var score: Int = 0
|
||||
@Environment(\.dismiss) var dismiss
|
||||
|
||||
let category: String
|
||||
|
||||
@State private var selectedAnswerIndex: Int? = nil
|
||||
@State private var isAnswered = false
|
||||
@State private var showExitAlert = false
|
||||
@@ -48,7 +50,7 @@ struct ContentView: View {
|
||||
score: viewModel.score,
|
||||
currentIndex: viewModel.currentQuestionIndex,
|
||||
total: viewModel.questions.count,
|
||||
colorForStep: { idx in colorForAnswer(at: idx) } // nutzt deine bestehende Funktion
|
||||
colorForStep: { idx in colorForAnswer(at: idx) }
|
||||
)
|
||||
|
||||
Text(frage.question)
|
||||
@@ -66,6 +68,7 @@ struct ContentView: View {
|
||||
maxValue: maxV,
|
||||
correctValue: correctV,
|
||||
unit: frage.unit ?? "",
|
||||
viewModel: viewModel,
|
||||
value: $estimationValue,
|
||||
submitted: $estimationSubmitted,
|
||||
gainedPoints: $estimationPoints
|
||||
@@ -123,9 +126,15 @@ struct ContentView: View {
|
||||
Text("Fragen werden geladen...")
|
||||
}
|
||||
}
|
||||
.navigationBarBackButtonHidden(!viewModel.isQuizFinished) // Button verstecken bei aktivem Quiz
|
||||
.onAppear {
|
||||
// Fragen für die Kategorie
|
||||
if viewModel.selectedCategory != category {
|
||||
viewModel.loadQuestions(for: category)
|
||||
}
|
||||
}
|
||||
.navigationBarBackButtonHidden(!viewModel.isQuizFinished)
|
||||
.toolbar {
|
||||
if !viewModel.isQuizFinished { // Custom Button nur bei aktivem Quiz
|
||||
if !viewModel.isQuizFinished {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button("Abbrechen") {
|
||||
showExitAlert = true
|
||||
@@ -167,7 +176,7 @@ struct ContentView: View {
|
||||
viewModel.selectedAnswers = Array(repeating: nil, count: viewModel.questions.count)
|
||||
}
|
||||
|
||||
func colorForAnswer(at index: Int) -> Color {
|
||||
private func colorForAnswer(at index: Int) -> Color {
|
||||
if index == viewModel.currentQuestionIndex,
|
||||
viewModel.selectedAnswers[index] == nil {
|
||||
return Color.blue // aktuelle Frage
|
||||
@@ -213,17 +222,6 @@ struct ContentView: View {
|
||||
|
||||
print("Score gespeichert: \(playerName) - \(viewModel.score) Punkte")
|
||||
}
|
||||
|
||||
private func pointsForEstimation(guess: Double, correct: Double, minValue: Double, maxValue: Double, maxPoints: Int = 3, thresholdPercent: Double = 0.3) -> Int {
|
||||
let span = maxValue - minValue
|
||||
guard span > 0 else { return 0 }
|
||||
let absError = abs(guess - correct)
|
||||
let relError = absError / span
|
||||
if relError >= thresholdPercent { return 0 }
|
||||
let ratio = 1.0 - (relError / thresholdPercent)
|
||||
return max(0, Int(round(Double(maxPoints) * ratio)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
//
|
||||
// Created by Paul on 08.08.25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct EstimationQuestionView: View {
|
||||
@@ -12,6 +11,7 @@ struct EstimationQuestionView: View {
|
||||
let maxValue: Double
|
||||
let correctValue: Double
|
||||
let unit: String
|
||||
let viewModel: ViewModel
|
||||
|
||||
@Binding var value: Double
|
||||
@Binding var submitted: Bool
|
||||
@@ -45,7 +45,7 @@ struct EstimationQuestionView: View {
|
||||
|
||||
if !submitted {
|
||||
Button {
|
||||
gainedPoints = pointsForEstimation(
|
||||
gainedPoints = viewModel.pointsForEstimation(
|
||||
guess: value,
|
||||
correct: correctValue,
|
||||
minValue: minValue,
|
||||
@@ -80,20 +80,3 @@ struct EstimationQuestionView: View {
|
||||
.padding(.horizontal)
|
||||
}
|
||||
}
|
||||
|
||||
private func pointsForEstimation(
|
||||
guess: Double,
|
||||
correct: Double,
|
||||
minValue: Double,
|
||||
maxValue: Double,
|
||||
maxPoints: Int = 3,
|
||||
thresholdPercent: Double = 0.3
|
||||
) -> Int {
|
||||
let span = maxValue - minValue
|
||||
guard span > 0 else { return 0 }
|
||||
let absError = abs(guess - correct)
|
||||
let relError = absError / span
|
||||
if relError >= thresholdPercent { return 0 }
|
||||
let ratio = 1.0 - (relError / thresholdPercent)
|
||||
return max(0, Int(round(Double(maxPoints) * ratio)))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ struct QuizHeader: View {
|
||||
Text("Punkte: \(score)")
|
||||
.font(.headline)
|
||||
|
||||
// Fortschrittsbalken
|
||||
HStack(spacing: 4) {
|
||||
ForEach(0..<total, id: \.self) { idx in
|
||||
Rectangle()
|
||||
|
||||
Reference in New Issue
Block a user