Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmbr73/468230447943e34dcfec01eafa95d362 to your computer and use it in GitHub Desktop.
Save nmbr73/468230447943e34dcfec01eafa95d362 to your computer and use it in GitHub Desktop.
This is the 'Education' part only - it's a mess already and so I did not go down the 'Entertainment' route.
//
// ContentView.swift
// Edut(r)ainMe - Day35
//
// Created by mbr73 on 04.10.22.
//
import SwiftUI
struct Question {
var multiplier: Int
var table: Int
var answer : Int?
init(_ multiplier: Int, _ table: Int) {
self.multiplier = multiplier
self.table = table
self.answer = nil
}
var hasCorrectAnswer: Bool {
answer ?? 0 == multiplier*table
}
var hasAnswer: Bool {
answer != nil
}
var string: String {
"\(multiplier) × \(table)"
}
}
extension Question: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(multiplier)
hasher.combine(table)
}
}
struct ContentView: View {
enum GameState {
case showingSettings
case isRunning
case showingResults
}
var gameStateTitle: String {
switch gameState {
case .showingSettings:
return "Settings"
case .isRunning:
return "Question \(currentQuestion + 1)/\(numberOfQuestionsSelected)"
case .showingResults:
return "Results"
}
}
@State private var gameState = GameState.showingSettings
let numberOfQuestionsOptions = [5, 10, 20]
@State private var numberOfQuestionsSelected = 5
@State private var multiplicationUpTo = 2
@State private var currentQuestion = 0
@State private var correctAnswers = 0
@State private var questions = Array<Question>()
@FocusState private var answerTextFieldFocused: Bool
func buildQuestions(upTo: Int, number: Int) {
questions = Array<Question>()
for i in 1...12 {
for j in 1...upTo {
questions.append(Question(i,j))
}
}
questions.shuffle()
questions.removeLast(upTo*12 - number)
}
var body: some View {
NavigationView {
List {
switch gameState {
case .showingSettings:
Section {
Stepper("Tables up to \(multiplicationUpTo)", value: $multiplicationUpTo, in: 2...12)
HStack {
Text("Questions")
Spacer()
Picker("Questions", selection: $numberOfQuestionsSelected) {
ForEach(numberOfQuestionsOptions, id: \.self) {
Text("\($0)")
}
}
.pickerStyle(.segmented)
}
} header: {
Text("Let /me EduT(r)ain U")
} footer: {
Text("Multiplication tables to practice are 1 up to \(multiplicationUpTo) by asking \(numberOfQuestionsSelected) questions.")
}
Section {
Button {
buildQuestions(upTo: multiplicationUpTo, number: numberOfQuestionsSelected)
currentQuestion = 0
correctAnswers = 0
answerTextFieldFocused = true
withAnimation {
gameState = .isRunning
}
} label: {
HStack {
Spacer()
Text("Go!")
Spacer()
}
}
}
case .isRunning:
Section {
HStack {
Text("What's") // Without the text the Spacer() causes an ugly gap!?!!
Spacer()
Text("\(questions[currentQuestion].string)")
.font(.largeTitle)
Spacer()
}
TextField("Type in your answer", value: $questions[currentQuestion].answer, format: .number)
.keyboardType(.decimalPad)
.focused($answerTextFieldFocused)
} header: {
Text("Question from table \(questions[currentQuestion].table):")
} footer: {
Text("Multiplication tables to practice are 1 up to \(multiplicationUpTo). This is a question from table \(questions[currentQuestion].table).")
}
case .showingResults:
Section {
ForEach(questions, id: \.self) { question in
HStack {
Text("\(question.string) = \(question.answer!)")
.foregroundColor(question.hasCorrectAnswer ? .black : .red )
//.font(.monospaced(.body)())
Spacer()
Text(question.hasCorrectAnswer ? "✅" : "❌")
}
}
} footer: {
Text("You had \(correctAnswers) out of \(numberOfQuestionsSelected) questions answered correctly.")
}
}
}
.navigationTitle(gameStateTitle)
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
if gameState == .isRunning {
Button("Abort") {
withAnimation {
gameState = .showingSettings
}
}
} else if gameState == .showingResults {
Button("Done") {
withAnimation {
gameState = .showingSettings
}
}
}
}
}
}.onSubmit {
if gameState == .isRunning {
let question = questions[currentQuestion]
if question.hasAnswer {
if question.hasCorrectAnswer
{ correctAnswers += 1
}
if currentQuestion+1 < questions.count {
currentQuestion += 1
} else {
withAnimation {
gameState = .showingResults
}
}
}
answerTextFieldFocused = true
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment