Mercurial > public > geoquiz
changeset 33:6d574bd1644f
refactor controllers
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Sat, 12 Nov 2022 11:18:30 +0100 |
parents | c62d6f92709d |
children | 6ec51a4ca897 |
files | GeoQuiz/Controllers/CityGameController.swift GeoQuiz/Controllers/CountryGameController.swift GeoQuiz/Controllers/GameProtocol+Extension.swift GeoQuiz/GuessTheCapitalView.swift GeoQuiz/GuessTheCountryView.swift GeoQuiz/GuessTheFlagView.swift GeoQuiz/GuessThePopulationView.swift GeoQuiz/Helpers/GameAlertsModifier.swift screenshots/iPad Pro/store/image2.jpeg screenshots/iPad Pro/store/image4.jpeg screenshots/iPhone 11/store/image2.jpeg screenshots/iPhone 11/store/image4.jpeg screenshots/iPhone 8/store/image2.jpeg screenshots/iPhone 8/store/image4.jpeg |
diffstat | 14 files changed, 59 insertions(+), 135 deletions(-) [+] |
line wrap: on
line diff
--- a/GeoQuiz/Controllers/CityGameController.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/Controllers/CityGameController.swift Sat Nov 12 11:18:30 2022 +0100 @@ -8,30 +8,27 @@ import Foundation import AVFAudio -class CityGameController: Game, ObservableObject { +@MainActor class CityGameController: Game, ObservableObject { - // Define type of generics + // Define generic type typealias T = CityModel.City + // Game var data: [String: T] var dataAsked = [String: T]() - // Data - @Published var correctAnswer = ( - key: String(), - value: T(country: String(), lat: Double(), lon: Double()) - ) - - // User @Published var userChoices = [String: T]() @Published var userScore = 0 @Published var userLives = 3 + + @Published var correctAnswer = (key: String(), value: T(country: String(), lat: Double(), lon: Double())) @Published var correctAnswers = [String: T]() @Published var wrongAnswers = [String: T]() // Alerts @Published var alertTitle = String() @Published var alertMessage = String() + @Published var showingEndGameAlert = false @Published var showingWrongAnswerAlert = false @Published var showingExitGameAlert = false @@ -45,11 +42,16 @@ init() { let data: CityModel = Bundle.main.decode("cities.json") - let shuffledCities = data.cities.shuffled().prefix(100) - + let shuffledCities = data.cities.shuffled() var cities = [String: T]() - for shuffledCity in shuffledCities { - cities[shuffledCity.key] = shuffledCity.value + + for _ in 1...10 { + let countryNames = cities.map { $0.value.country } + let city = shuffledCities.first(where: { + !countryNames.contains($0.value.country) + })! + + cities[city.key] = city.value } self.data = cities @@ -63,54 +65,8 @@ } } - askQuestion { - selector() - } + ask() } } -extension CityGameController { - func selector() { - - // Get random choices - var userChoices = [String: T]() - - while userChoices.count < 2 { - if let choice = data.randomElement() { - let userChoicesCountry = userChoices.map { $0.value.country } - - if !userChoicesCountry.contains(choice.value.country) { - userChoices[choice.key] = choice.value - } - } else { - fatalError("Couldn't get a random value from data") - } - } - - // Get correct answer - let randomCityKeys = data.keys.shuffled() - let userChoicesCountry = userChoices.map { $0.value.country } - - let correctCityKey = randomCityKeys.first(where: { - !userChoices.keys.contains($0) && // Avoid duplicated cities - !dataAsked.keys.contains($0) && // Avoid cities already asked - !userChoicesCountry.contains(data[$0]!.country) // Avoid duplicated country names in userChoices - }) - // Unwrap optional - if let correctCityKey = correctCityKey { - let correctCityValue = data[correctCityKey]! - - userChoices[correctCityKey] = correctCityValue - dataAsked[correctCityKey] = correctCityValue - - let correctAnswer = (key: correctCityKey, value: correctCityValue) - self.correctAnswer = correctAnswer - } else { - fatalError("Couldn't unwrap optional value") - } - - self.userChoices = userChoices - } -} -
--- a/GeoQuiz/Controllers/CountryGameController.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/Controllers/CountryGameController.swift Sat Nov 12 11:18:30 2022 +0100 @@ -16,7 +16,6 @@ var data: [String: T] var dataAsked = [String: T]() - // Data @Published var correctAnswer = ( key: String(), value: T(flag: String(), currency: String(), population: Int(), capital: String()) @@ -45,15 +44,17 @@ init() { let data: CountryModel = Bundle.main.decode("countries.json") - let shuffledCountries = data.countries.shuffled().prefix(100) + let shuffledCountries = data.countries.shuffled().prefix(5) + var countries = [String: T]() - var countries = [String: T]() for shuffledCountry in shuffledCountries { countries[shuffledCountry.key] = shuffledCountry.value } self.data = countries + print(countries) + let user = UserController() userLives = user.data.numberOfLives @@ -63,47 +64,6 @@ } } - askQuestion { - selector() - } + ask() } } - -extension CountryGameController { - func selector() { - - // Get random choices - var userChoices = [String: T]() - - while userChoices.count < 2 { - if let choice = data.randomElement() { - userChoices[choice.key] = choice.value - } else { - fatalError("Couldn't get a random value from data") - } - } - - // Get correct answer - let randomCountryKeys = data.keys.shuffled() - - let correctCountryKey = randomCountryKeys.first(where: { - !userChoices.keys.contains($0) && // Avoid duplicated countries - !dataAsked.keys.contains($0) // Avoid countries already asked - }) - - // Unwrap correct answer - if let correctCountryKey = correctCountryKey { - let correctCountryValue = data[correctCountryKey]! - - userChoices[correctCountryKey] = correctCountryValue - dataAsked[correctCountryKey] = correctCountryValue - - let correctAnswer = (key: correctCountryKey, value: correctCountryValue) - self.correctAnswer = correctAnswer - } else { - fatalError("Couldn't unwrap optional value") - } - - self.userChoices = userChoices - } -}
--- a/GeoQuiz/Controllers/GameProtocol+Extension.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/Controllers/GameProtocol+Extension.swift Sat Nov 12 11:18:30 2022 +0100 @@ -18,7 +18,7 @@ case guessThePopulation } -protocol Game: ObservableObject { +@MainActor protocol Game: ObservableObject { // Define generic type associatedtype T: Equatable @@ -26,18 +26,19 @@ // Game var data: [String: T] { get set} var dataAsked: [String: T] { get set } - var correctAnswer: (key: String, value: T) { get set } - // User var userChoices: [String: T] { get set } var userScore: Int { get set } var userLives: Int { get set } + + var correctAnswer: (key: String, value: T) { get set } var correctAnswers: [String: T] { get set } var wrongAnswers: [String: T] { get set } // Alerts var alertTitle: String { get set } var alertMessage: String { get set } + var showingEndGameAlert: Bool { get set } var showingWrongAnswerAlert: Bool { get set } var showingExitGameAlert: Bool { get set } @@ -48,8 +49,6 @@ // Sound effects var player: AVAudioPlayer? { get set } - - func selector() } extension Game { @@ -57,7 +56,8 @@ dataAsked.count } - func askQuestion(selector: () -> Void) { + // MARK: - Ask new question + func ask() { guard questionCounter < data.count else { alertTitle = "⭐️ Congratulations ⭐️" alertMessage = "You completed the game." @@ -66,10 +66,28 @@ return } - selector() + var userChoices = [String: T]() + + while userChoices.count < 2 { + let choice = data.randomElement()! + userChoices[choice.key] = choice.value + } + + let correctKey = data.keys.shuffled().first(where: { + !userChoices.keys.contains($0) && // Avoid duplicated items + !dataAsked.keys.contains($0) // Avoid items already asked + })! + + let correctValue = data[correctKey]! + + userChoices[correctKey] = correctValue + dataAsked[correctKey] = correctValue + correctAnswer = (key: correctKey, value: correctValue) + self.userChoices = userChoices } - func answer(choice: (key: String, value: T), wrongMessage: String, selector: () -> Void) { + // MARK: - Answer question + func answer(choice: (key: String, value: T), wrongMessage: String) { let haptics = HapticsController() if correctAnswer == choice { @@ -82,17 +100,15 @@ } correctAnswers[correctAnswer.key] = correctAnswer.value - askQuestion { - selector() - } + ask() } else { haptics.error() playSound("wrongAnswer") - withAnimation(.easeIn(duration: 0.5)) { - livesScaleAmount += 1 - userLives -= 1 - } +// withAnimation(.easeIn(duration: 0.5)) { +// livesScaleAmount += 1 +// userLives -= 1 +// } wrongAnswers[choice.key] = choice.value @@ -115,6 +131,7 @@ } } + // MARK: - Save game func save(_ gameType: GameType, with moc: NSManagedObjectContext) { let playedGame = PlayedGame(context: moc) @@ -131,6 +148,7 @@ } } + // MARK: - Play sound effect private func playSound(_ filename: String) { let user = UserController()
--- a/GeoQuiz/GuessTheCapitalView.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/GuessTheCapitalView.swift Sat Nov 12 11:18:30 2022 +0100 @@ -65,9 +65,7 @@ gameController.answer( choice: (key: countryName, value: gameController.data[countryName]!), wrongMessage: "That's the capital of \(countryName)" - ) { - gameController.selector() - } + ) } label: { AnswerButton( name: gameController.data[countryName]!.capital,
--- a/GeoQuiz/GuessTheCountryView.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/GuessTheCountryView.swift Sat Nov 12 11:18:30 2022 +0100 @@ -48,9 +48,7 @@ gameController.answer( choice: (key: cityName, value: gameController.data[cityName]!), wrongMessage: "\(gameController.correctAnswer.key) is located in \(gameController.correctAnswer.value.country)" - ) { - gameController.selector() - } + ) } label: { AnswerButton( name: gameController.data[cityName]!.country,
--- a/GeoQuiz/GuessTheFlagView.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/GuessTheFlagView.swift Sat Nov 12 11:18:30 2022 +0100 @@ -48,9 +48,7 @@ gameController.answer( choice: (key: countryName, value: gameController.data[countryName]!), wrongMessage: "That's the flag of \(countryName)" - ) { - gameController.selector() - } + ) } label: { /*
--- a/GeoQuiz/GuessThePopulationView.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/GuessThePopulationView.swift Sat Nov 12 11:18:30 2022 +0100 @@ -65,9 +65,7 @@ gameController.answer( choice: (key: countryName, value: gameController.data[countryName]!), wrongMessage: "That's the population of \(countryName)" - ) { - gameController.selector() - } + ) } label: { let population = gameController.data[countryName]!.population AnswerButton(
--- a/GeoQuiz/Helpers/GameAlertsModifier.swift Fri Nov 11 09:05:41 2022 +0100 +++ b/GeoQuiz/Helpers/GameAlertsModifier.swift Sat Nov 12 11:18:30 2022 +0100 @@ -20,9 +20,7 @@ content .alert(gameController.alertTitle, isPresented: $gameController.showingWrongAnswerAlert) { Button("Continue", role: .cancel) { - gameController.askQuestion { - gameController.selector() - } + gameController.ask() } } message: { Text(gameController.alertMessage)