fix: some adjustments for estimation questions
This commit is contained in:
@@ -184,21 +184,61 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Schätzen": [
|
"Schätzen": [
|
||||||
{
|
{
|
||||||
"type": "estimation",
|
"type": "estimation",
|
||||||
"question": "Wie hoch ist der Eiffelturm?",
|
"question": "Wie hoch ist der Eiffelturm?",
|
||||||
"minValue": 0,
|
"minValue": 100,
|
||||||
"maxValue": 1000,
|
"maxValue": 350,
|
||||||
"correctValue": 330,
|
"correctValue": 330,
|
||||||
"unit": "m"
|
"unit": "m"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "estimation",
|
"type": "estimation",
|
||||||
"question": "In welchem Jahr begann der Bau des Kölner Doms?",
|
"question": "In welchem Jahr begann der Bau des Kölner Doms?",
|
||||||
"minValue": 1000,
|
"minValue": 1000,
|
||||||
"maxValue": 2025,
|
"maxValue": 1900,
|
||||||
"correctValue": 1248,
|
"correctValue": 1248,
|
||||||
"unit": "Jahr"
|
"unit": "Jahr"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"type": "estimation",
|
||||||
|
"question": "Wie weit ist die Entfernung zwischen Berlin und New York (Luftlinie)?",
|
||||||
|
"minValue": 5000,
|
||||||
|
"maxValue": 10000,
|
||||||
|
"correctValue": 6380,
|
||||||
|
"unit": "km"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "estimation",
|
||||||
|
"question": "Wie hoch ist der Mount Everest?",
|
||||||
|
"minValue": 2000,
|
||||||
|
"maxValue": 10000,
|
||||||
|
"correctValue": 8848,
|
||||||
|
"unit": "m"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "estimation",
|
||||||
|
"question": "Wie viele Kilometer beträgt der Äquatorumfang der Erde?",
|
||||||
|
"minValue": 20000,
|
||||||
|
"maxValue": 50000,
|
||||||
|
"correctValue": 40075,
|
||||||
|
"unit": "km"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "estimation",
|
||||||
|
"question": "Wie tief ist der Marianengraben?",
|
||||||
|
"minValue": 1000,
|
||||||
|
"maxValue": 20000,
|
||||||
|
"correctValue": 11000,
|
||||||
|
"unit": "m"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "estimation",
|
||||||
|
"question": "In welchem Jahr wurde die Glühbirne von Thomas Edison patentiert?",
|
||||||
|
"minValue": 1700,
|
||||||
|
"maxValue": 2000,
|
||||||
|
"correctValue": 1879,
|
||||||
|
"unit": ""
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,20 +79,16 @@ class ViewModel: ObservableObject {
|
|||||||
func pointsForEstimation(
|
func pointsForEstimation(
|
||||||
guess: Double,
|
guess: Double,
|
||||||
correct: Double,
|
correct: Double,
|
||||||
minValue: Double,
|
maxPoints: Int = 1,
|
||||||
maxValue: Double,
|
|
||||||
maxPoints: Int = 3,
|
|
||||||
thresholdPercent: Double = 0.3
|
|
||||||
) -> Int {
|
) -> Int {
|
||||||
let span = maxValue - minValue
|
let absError = abs(guess - correct) // Absolute Abweichung
|
||||||
guard span > 0 else { return 0 }
|
let relError = absError / abs(correct) // Relative Abweichung
|
||||||
|
|
||||||
let absError = abs(guess - correct)
|
if relError <= 0.1 {
|
||||||
let relError = absError / span
|
return maxPoints
|
||||||
|
} else {
|
||||||
if relError >= thresholdPercent { return 0 }
|
return 0
|
||||||
|
}
|
||||||
let ratio = 1.0 - (relError / thresholdPercent)
|
|
||||||
return max(0, Int(round(Double(maxPoints) * ratio)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,33 +7,27 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct EstimationQuestionView: View {
|
struct EstimationQuestionView: View {
|
||||||
|
let questionID: AnyHashable // <- neu
|
||||||
let minValue: Double
|
let minValue: Double
|
||||||
let maxValue: Double
|
let maxValue: Double
|
||||||
let correctValue: Double
|
let correctValue: Double
|
||||||
let unit: String
|
let unit: String
|
||||||
let viewModel: ViewModel
|
let viewModel: ViewModel
|
||||||
|
|
||||||
@Binding var value: Double
|
@Binding var value: Double
|
||||||
@Binding var submitted: Bool
|
@Binding var submitted: Bool
|
||||||
@Binding var gainedPoints: Int
|
@Binding var gainedPoints: Int
|
||||||
let onSubmit: (Int) -> Void
|
let onSubmit: (Int) -> Void
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 16) {
|
VStack(spacing: 16) {
|
||||||
Slider(
|
Slider(
|
||||||
value: Binding(
|
value: $value,
|
||||||
get: { value },
|
|
||||||
set: { value = min(max($0, minValue), maxValue) } // clamp
|
|
||||||
),
|
|
||||||
in: minValue...maxValue,
|
in: minValue...maxValue,
|
||||||
step: (maxValue - minValue) > 200 ? 1 : 0.5
|
step: (maxValue - minValue) > 200 ? 1 : 0.5
|
||||||
)
|
)
|
||||||
.onAppear {
|
.disabled(submitted)
|
||||||
if value < minValue || value > maxValue {
|
|
||||||
value = (minValue + maxValue) / 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text("\(Int(minValue)) \(unit)")
|
Text("\(Int(minValue)) \(unit)")
|
||||||
Spacer()
|
Spacer()
|
||||||
@@ -42,14 +36,12 @@ struct EstimationQuestionView: View {
|
|||||||
Text("\(Int(maxValue)) \(unit)")
|
Text("\(Int(maxValue)) \(unit)")
|
||||||
}
|
}
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
|
||||||
if !submitted {
|
if !submitted {
|
||||||
Button {
|
Button {
|
||||||
gainedPoints = viewModel.pointsForEstimation(
|
gainedPoints = viewModel.pointsForEstimation(
|
||||||
guess: value,
|
guess: value,
|
||||||
correct: correctValue,
|
correct: correctValue
|
||||||
minValue: minValue,
|
|
||||||
maxValue: maxValue
|
|
||||||
)
|
)
|
||||||
submitted = true
|
submitted = true
|
||||||
onSubmit(gainedPoints)
|
onSubmit(gainedPoints)
|
||||||
@@ -66,7 +58,7 @@ struct EstimationQuestionView: View {
|
|||||||
let diff = abs(value - correctValue)
|
let diff = abs(value - correctValue)
|
||||||
let span = maxValue - minValue
|
let span = maxValue - minValue
|
||||||
let rel = span > 0 ? (diff / span) : 1.0
|
let rel = span > 0 ? (diff / span) : 1.0
|
||||||
|
|
||||||
Text("✅ Richtiger Wert: \(Int(correctValue)) \(unit)")
|
Text("✅ Richtiger Wert: \(Int(correctValue)) \(unit)")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.foregroundColor(.green)
|
.foregroundColor(.green)
|
||||||
@@ -78,5 +70,12 @@ struct EstimationQuestionView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
|
// bei jedem Fragewechsel
|
||||||
|
.task(id: questionID) {
|
||||||
|
value = minValue
|
||||||
|
submitted = false
|
||||||
|
gainedPoints = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ struct QuizView: View {
|
|||||||
let correctV = frage.correctValue {
|
let correctV = frage.correctValue {
|
||||||
// Estimation
|
// Estimation
|
||||||
EstimationQuestionView(
|
EstimationQuestionView(
|
||||||
|
questionID: viewModel.currentQuestionIndex, // <- neu
|
||||||
minValue: minV,
|
minValue: minV,
|
||||||
maxValue: maxV,
|
maxValue: maxV,
|
||||||
correctValue: correctV,
|
correctValue: correctV,
|
||||||
@@ -85,7 +86,6 @@ struct QuizView: View {
|
|||||||
if estimationSubmitted {
|
if estimationSubmitted {
|
||||||
Button {
|
Button {
|
||||||
viewModel.loadNextQuestion()
|
viewModel.loadNextQuestion()
|
||||||
// Reset für nächste Estimation
|
|
||||||
estimationSubmitted = false
|
estimationSubmitted = false
|
||||||
isAnswered = false
|
isAnswered = false
|
||||||
selectedAnswerIndex = nil
|
selectedAnswerIndex = nil
|
||||||
|
|||||||
Reference in New Issue
Block a user