# HG changeset patch # User Dennis C. M. # Date 1665047674 -7200 # Node ID e09959b4e4a8cba523981289335648a7addaa160 # Parent d945e52b07044f3344d2d30e8e90e26970554efa fix bugs diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Assets.xcassets/Flags/np.imageset/np@1x.png Binary file GeoQuiz/Assets.xcassets/Flags/np.imageset/np@1x.png has changed diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Assets.xcassets/Flags/np.imageset/np@2x.png Binary file GeoQuiz/Assets.xcassets/Flags/np.imageset/np@2x.png has changed diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Assets.xcassets/heart.imageset/Contents.json --- 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 - } -} diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Assets.xcassets/heart.imageset/heart.png Binary file GeoQuiz/Assets.xcassets/heart.imageset/heart.png has changed diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Assets.xcassets/heart.imageset/heart@2x.png Binary file GeoQuiz/Assets.xcassets/heart.imageset/heart@2x.png has changed diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Assets.xcassets/heart.imageset/heart@3x.png Binary file GeoQuiz/Assets.xcassets/heart.imageset/heart@3x.png has changed diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/ContentView.swift --- 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, diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/GuessTheCapitalView.swift --- 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, diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/GuessTheCountryView.swift --- 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, diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/GuessTheFlagView.swift --- 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) diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/GuessThePopulationView.swift --- 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!") } } diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Helpers/AnswerButton.swift --- 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()) diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Helpers/CityMap.swift --- 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()) +// } +//} diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Helpers/FlagImage.swift --- 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) } } diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Helpers/GameAlertsModifier.swift --- 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) diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Helpers/GameToolbar.swift --- 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) } diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Logic/CityGame.swift --- 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 } } diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Logic/CountryGame.swift --- 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 + } +} diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/Logic/Game.swift --- 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) { diff -r d945e52b0704 -r e09959b4e4a8 GeoQuiz/ProfileModalView.swift --- a/GeoQuiz/ProfileModalView.swift Tue Oct 04 18:54:24 2022 +0200 +++ b/GeoQuiz/ProfileModalView.swift Thu Oct 06 11:14:34 2022 +0200 @@ -9,7 +9,7 @@ struct ProfileModalView: View { var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + Text("Hello, World!") } } diff -r d945e52b0704 -r e09959b4e4a8 README.md --- a/README.md Tue Oct 04 18:54:24 2022 +0200 +++ b/README.md Thu Oct 06 11:14:34 2022 +0200 @@ -1,1 +1,1 @@ -geoquiz-app +# geoquiz-app