Mercurial > public > geoquiz
changeset 8:e09959b4e4a8
fix bugs
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Thu, 06 Oct 2022 11:14:34 +0200 |
parents | d945e52b0704 |
children | 3540c7efc216 |
files | GeoQuiz/Assets.xcassets/Flags/np.imageset/np@1x.png GeoQuiz/Assets.xcassets/Flags/np.imageset/np@2x.png GeoQuiz/Assets.xcassets/heart.imageset/Contents.json GeoQuiz/Assets.xcassets/heart.imageset/heart.png GeoQuiz/Assets.xcassets/heart.imageset/heart@2x.png GeoQuiz/Assets.xcassets/heart.imageset/heart@3x.png GeoQuiz/ContentView.swift GeoQuiz/GuessTheCapitalView.swift GeoQuiz/GuessTheCountryView.swift GeoQuiz/GuessTheFlagView.swift GeoQuiz/GuessThePopulationView.swift GeoQuiz/Helpers/AnswerButton.swift GeoQuiz/Helpers/CityMap.swift GeoQuiz/Helpers/FlagImage.swift GeoQuiz/Helpers/GameAlertsModifier.swift GeoQuiz/Helpers/GameToolbar.swift GeoQuiz/Logic/CityGame.swift GeoQuiz/Logic/CountryGame.swift GeoQuiz/Logic/Game.swift GeoQuiz/ProfileModalView.swift README.md |
diffstat | 21 files changed, 172 insertions(+), 112 deletions(-) [+] |
line wrap: on
line diff
--- a/GeoQuiz/Assets.xcassets/heart.imageset/Contents.json Tue Oct 04 18:54:24 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "filename" : "heart.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "heart@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "heart@3x.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -}
--- a/GeoQuiz/ContentView.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/ContentView.swift Thu Oct 06 11:14:34 2022 +0200 @@ -36,7 +36,7 @@ level: "Level 3", symbol: "globe.americas.fill", name: "Guess the country" ) } -// + // NavigationLink( // destination: Text("Guess the population"), // tag: GameName.guessThePopulation,
--- a/GeoQuiz/GuessTheCapitalView.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/GuessTheCapitalView.swift Thu Oct 06 11:14:34 2022 +0200 @@ -45,7 +45,9 @@ VStack { ForEach(Array(game.userChoices.keys), id: \.self) { countryName in Button { - game.answer((key: countryName, value: game.data[countryName]!)) + game.answer((key: countryName, value: game.data[countryName]!)) { + game.selector() + } } label: { AnswerButton( optionName: game.data[countryName]!.capital,
--- a/GeoQuiz/GuessTheCountryView.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/GuessTheCountryView.swift Thu Oct 06 11:14:34 2022 +0200 @@ -21,7 +21,7 @@ Spacer() - CityMap(game: game) + CityMap(game: game, geo: geo) Spacer() @@ -43,7 +43,9 @@ VStack { ForEach(Array(game.userChoices.keys), id: \.self) { cityName in Button { - game.answer((key: cityName, value: game.data[cityName]!)) + game.answer((key: cityName, value: game.data[cityName]!)) { + game.selector() + } } label: { AnswerButton( optionName: game.data[cityName]!.country,
--- a/GeoQuiz/GuessTheFlagView.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/GuessTheFlagView.swift Thu Oct 06 11:14:34 2022 +0200 @@ -38,7 +38,9 @@ ForEach(Array(game.userChoices.keys), id: \.self) { countryName in Button { - game.answer((key: countryName, value: game.data[countryName]!)) + game.answer((key: countryName, value: game.data[countryName]!)) { + game.selector() + } } label: { FlagImage(flagSymbol: game.data[countryName]!.flag, cornerRadius: 20) .shadow(radius: 10)
--- a/GeoQuiz/GuessThePopulationView.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/GuessThePopulationView.swift Thu Oct 06 11:14:34 2022 +0200 @@ -9,7 +9,7 @@ struct GuessThePopulationView: View { var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + Text("Hello, World!") } }
--- a/GeoQuiz/Helpers/AnswerButton.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Helpers/AnswerButton.swift Thu Oct 06 11:14:34 2022 +0200 @@ -13,7 +13,7 @@ var body: some View { RoundedRectangle(cornerRadius: 15) - .foregroundStyle(.regularMaterial) + .foregroundStyle(.ultraThickMaterial) .overlay( Text(optionName) .font(.title2.bold())
--- a/GeoQuiz/Helpers/CityMap.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Helpers/CityMap.swift Thu Oct 06 11:14:34 2022 +0200 @@ -6,13 +6,17 @@ // import SwiftUI +import MapKit struct CityMap: View { @ObservedObject var game: CityGame + @State private var mapImage: UIImage? = nil + + let geo: GeometryProxy var body: some View { - Group { - if let mapImage = game.mapImage { + VStack { + if let mapImage = mapImage { Image(uiImage: mapImage) .resizable() .scaledToFit() @@ -22,11 +26,42 @@ ProgressView() } } + .onChange(of: game.correctAnswer.value) { _ in getMapImage() } + .onAppear(perform: getMapImage) + } + + private func getMapImage() { + let region = MKCoordinateRegion( + center: CLLocationCoordinate2D( + latitude: game.correctAnswer.value.lat, + longitude: game.correctAnswer.value.lon + ), + span: MKCoordinateSpan( + latitudeDelta: 0.1, + longitudeDelta: 0.1 + ) + ) + + // Map options + let mapOptions = MKMapSnapshotter.Options() + mapOptions.region = region + mapOptions.size = CGSize(width: geo.size.width * 0.8, height: geo.size.width * 0.8) + mapOptions.pointOfInterestFilter = .excludingAll + + // Create the snapshotter and run it + let snapshotter = MKMapSnapshotter(options: mapOptions) + snapshotter.start { (snapshot, error) in + if let snapshot = snapshot { + self.mapImage = snapshot.image + } else if let error = error { + print(error.localizedDescription) + } + } } } -struct CityMap_Previews: PreviewProvider { - static var previews: some View { - CityMap(game: CityGame()) - } -} +//struct CityMap_Previews: PreviewProvider { +// static var previews: some View { +// CityMap(game: CityGame()) +// } +//}
--- a/GeoQuiz/Helpers/FlagImage.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Helpers/FlagImage.swift Thu Oct 06 11:14:34 2022 +0200 @@ -24,7 +24,7 @@ struct FlagImage_Previews: PreviewProvider { static var previews: some View { - FlagImage(flagSymbol: "es", cornerRadius: 20) + FlagImage(flagSymbol: "np", cornerRadius: 20) .frame(height: 130) } }
--- a/GeoQuiz/Helpers/GameAlertsModifier.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Helpers/GameAlertsModifier.swift Thu Oct 06 11:14:34 2022 +0200 @@ -14,20 +14,32 @@ func body(content: Content) -> some View { content .alert(game.alertTitle, isPresented: $game.showingWrongAnswerAlert) { - Button("Continue", role: .cancel) { game.askQuestion() } + Button("Continue", role: .cancel) { + game.askQuestion { + game.selector() + } + } } message: { Text(game.alertMessage) } .alert(game.alertTitle, isPresented: $game.showingGameOverAlert) { - Button("Try again") { game.reset() } + Button("Try again") { + game.reset { + game.selector() + } + } Button("Exit", role: .cancel) { dismiss()} } message: { Text(game.alertMessage) } .alert(game.alertTitle, isPresented: $game.showingEndGameAlert) { - Button("Play again") { game.reset() } + Button("Play again") { + game.reset() { + game.selector() + } + } Button("Exit", role: .cancel) { dismiss() } } message: { Text(game.alertMessage)
--- a/GeoQuiz/Helpers/GameToolbar.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Helpers/GameToolbar.swift Thu Oct 06 11:14:34 2022 +0200 @@ -24,7 +24,7 @@ .padding(10) .background( Circle() - .foregroundStyle(.regularMaterial) + .foregroundStyle(.ultraThickMaterial) ) } } @@ -37,8 +37,14 @@ .foregroundColor(color) .padding() .background( - Circle() - .foregroundStyle(.regularMaterial) + Group { + if game.userScore < 1000 { + Circle() + } else { + Capsule() + } + } + .foregroundStyle(.ultraThickMaterial) ) } .font(.title2) @@ -55,7 +61,7 @@ .padding(10) .background( Capsule() - .foregroundStyle(.regularMaterial) + .foregroundStyle(.ultraThickMaterial) ) .scaleEffect(game.livesScaleAmount) }
--- a/GeoQuiz/Logic/CityGame.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Logic/CityGame.swift Thu Oct 06 11:14:34 2022 +0200 @@ -8,7 +8,6 @@ import Foundation import AVFAudio import SwiftUI -import MapKit class CityGame: Game, ObservableObject { @@ -18,12 +17,11 @@ var data: [String: T] var dataAsked = [String: T]() - @Published var mapImage: UIImage? = nil - @Published var correctAnswer = (key: String(), value: T(country: String(), lat: Double(), lon: Double())) { - willSet { - getMapImage(lat: newValue.value.lat, lon: newValue.value.lon) - } - } + // Data + @Published var correctAnswer = ( + key: String(), + value: T(country: String(), lat: Double(), lon: Double()) + ) // User @Published var userChoices = [String: T]() @@ -50,38 +48,48 @@ init() { let data: CityModel = load("cities.json") self.data = data.cities - askQuestion() + askQuestion { + selector() + } } } extension CityGame { - func getMapImage(lat: Double, lon: Double) { - let region = MKCoordinateRegion( - center: CLLocationCoordinate2D( - latitude: lat, - longitude: lon - ), - span: MKCoordinateSpan( - latitudeDelta: 1.0, - longitudeDelta: 1.0 - ) - ) - - // Map options - let mapOptions = MKMapSnapshotter.Options() - mapOptions.region = region - mapOptions.size = CGSize(width: 600, height: 600) - mapOptions.showsBuildings = true - - // Create the snapshotter and run it - let snapshotter = MKMapSnapshotter(options: mapOptions) - snapshotter.start { (snapshot, error) in - if let snapshot = snapshot { - self.mapImage = snapshot.image - } else if let error = error { - print(error.localizedDescription) + 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 question asked (correct answer) + let userChoicesCountry = userChoices.map { $0.value.country } + let correctAnswer = data.first(where: { + !userChoices.keys.contains($0.key) && // Avoid duplicated cities + !dataAsked.keys.contains($0.key) && // Avoid cities already asked + !userChoicesCountry.contains($0.value.country) // Avoid duplicated country names in userChoices + }) + + // Unwrap optional + if let correctAnswer = correctAnswer { + userChoices[correctAnswer.key] = correctAnswer.value + dataAsked[correctAnswer.key] = correctAnswer.value + self.correctAnswer = correctAnswer + } else { + fatalError("Couldn't unwrap optional value") + } + + self.userChoices = userChoices } }
--- a/GeoQuiz/Logic/CountryGame.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Logic/CountryGame.swift Thu Oct 06 11:14:34 2022 +0200 @@ -47,6 +47,41 @@ init() { let data: CountryModel = load("countries.json") self.data = data.countries - askQuestion() + askQuestion { + selector() + } } } + +extension CountryGame { + 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 question asked (correct answer) + let correctAnswer = data.first(where: { + !userChoices.keys.contains($0.key) && // Avoid duplicated countries + !dataAsked.keys.contains($0.key) // Avoid countries already asked + }) + + // Unwrap optional + if let correctAnswer = correctAnswer { + userChoices[correctAnswer.key] = correctAnswer.value + dataAsked[correctAnswer.key] = correctAnswer.value + self.correctAnswer = correctAnswer + } else { + fatalError("Couldn't unwrap optional value") + } + + self.userChoices = userChoices + } +}
--- a/GeoQuiz/Logic/Game.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/Logic/Game.swift Thu Oct 06 11:14:34 2022 +0200 @@ -40,6 +40,8 @@ // Sound effects var player: AVAudioPlayer? { get set } + + func selector() } extension Game { @@ -47,7 +49,7 @@ dataAsked.count } - func askQuestion() { + func askQuestion(selector: () -> Void) { guard questionCounter < data.count else { alertTitle = "⭐️ Congratulations ⭐️" alertMessage = "You completed the game." @@ -56,35 +58,10 @@ return } - // 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 question asked (correct answer) - let correctAnswer = data.first(where: { - !userChoices.keys.contains($0.key) && !dataAsked.keys.contains($0.key) - }) - - // Unwrap optional - if let correctAnswer = correctAnswer { - userChoices[correctAnswer.key] = correctAnswer.value - dataAsked[correctAnswer.key] = correctAnswer.value - self.correctAnswer = correctAnswer - } else { - fatalError("Couldn't unwrap optional value") - } - - self.userChoices = userChoices + selector() } - func answer(_ choice: (key: String, value: T)) { + func answer(_ choice: (key: String, value: T), selector: () -> Void) { if correctAnswer == choice { hapticSuccess() playSound("correctAnswer") @@ -95,7 +72,9 @@ } correctAnswers[correctAnswer.key] = correctAnswer.value - askQuestion() + askQuestion { + selector() + } } else { hapticError() playSound("wrongAnswer") @@ -126,13 +105,15 @@ } } - func reset() { + func reset(selector: () -> Void) { dataAsked = [String: T]() userScore = 0 userLives = 3 correctAnswers = [String: T]() wrongAnswers = [String: T]() - askQuestion() + askQuestion { + selector() + } } private func playSound(_ filename: String) {