Mercurial > public > geoquiz
comparison GeoQuiz/Controllers/CityGameController.swift @ 33:6d574bd1644f
refactor controllers
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Sat, 12 Nov 2022 11:18:30 +0100 |
parents | eb23effeede7 |
children | 6ec51a4ca897 |
comparison
equal
deleted
inserted
replaced
32:c62d6f92709d | 33:6d574bd1644f |
---|---|
6 // | 6 // |
7 | 7 |
8 import Foundation | 8 import Foundation |
9 import AVFAudio | 9 import AVFAudio |
10 | 10 |
11 class CityGameController: Game, ObservableObject { | 11 @MainActor class CityGameController: Game, ObservableObject { |
12 | 12 |
13 // Define type of generics | 13 // Define generic type |
14 typealias T = CityModel.City | 14 typealias T = CityModel.City |
15 | 15 |
16 // Game | |
16 var data: [String: T] | 17 var data: [String: T] |
17 var dataAsked = [String: T]() | 18 var dataAsked = [String: T]() |
18 | 19 |
19 // Data | |
20 @Published var correctAnswer = ( | |
21 key: String(), | |
22 value: T(country: String(), lat: Double(), lon: Double()) | |
23 ) | |
24 | |
25 // User | |
26 @Published var userChoices = [String: T]() | 20 @Published var userChoices = [String: T]() |
27 @Published var userScore = 0 | 21 @Published var userScore = 0 |
28 @Published var userLives = 3 | 22 @Published var userLives = 3 |
23 | |
24 @Published var correctAnswer = (key: String(), value: T(country: String(), lat: Double(), lon: Double())) | |
29 @Published var correctAnswers = [String: T]() | 25 @Published var correctAnswers = [String: T]() |
30 @Published var wrongAnswers = [String: T]() | 26 @Published var wrongAnswers = [String: T]() |
31 | 27 |
32 // Alerts | 28 // Alerts |
33 @Published var alertTitle = String() | 29 @Published var alertTitle = String() |
34 @Published var alertMessage = String() | 30 @Published var alertMessage = String() |
31 | |
35 @Published var showingEndGameAlert = false | 32 @Published var showingEndGameAlert = false |
36 @Published var showingWrongAnswerAlert = false | 33 @Published var showingWrongAnswerAlert = false |
37 @Published var showingExitGameAlert = false | 34 @Published var showingExitGameAlert = false |
38 | 35 |
39 // Animations | 36 // Animations |
43 // Sound effects | 40 // Sound effects |
44 @Published var player: AVAudioPlayer? | 41 @Published var player: AVAudioPlayer? |
45 | 42 |
46 init() { | 43 init() { |
47 let data: CityModel = Bundle.main.decode("cities.json") | 44 let data: CityModel = Bundle.main.decode("cities.json") |
48 let shuffledCities = data.cities.shuffled().prefix(100) | 45 let shuffledCities = data.cities.shuffled() |
46 var cities = [String: T]() | |
49 | 47 |
50 var cities = [String: T]() | 48 for _ in 1...10 { |
51 for shuffledCity in shuffledCities { | 49 let countryNames = cities.map { $0.value.country } |
52 cities[shuffledCity.key] = shuffledCity.value | 50 let city = shuffledCities.first(where: { |
51 !countryNames.contains($0.value.country) | |
52 })! | |
53 | |
54 cities[city.key] = city.value | |
53 } | 55 } |
54 | 56 |
55 self.data = cities | 57 self.data = cities |
56 | 58 |
57 let user = UserController() | 59 let user = UserController() |
61 if let decodedUserData = try? JSONDecoder().decode(UserDataModel.self, from: userData) { | 63 if let decodedUserData = try? JSONDecoder().decode(UserDataModel.self, from: userData) { |
62 userLives = decodedUserData.numberOfLives | 64 userLives = decodedUserData.numberOfLives |
63 } | 65 } |
64 } | 66 } |
65 | 67 |
66 askQuestion { | 68 ask() |
67 selector() | |
68 } | |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 extension CityGameController { | |
73 func selector() { | |
74 | |
75 // Get random choices | |
76 var userChoices = [String: T]() | |
77 | |
78 while userChoices.count < 2 { | |
79 if let choice = data.randomElement() { | |
80 let userChoicesCountry = userChoices.map { $0.value.country } | |
81 | |
82 if !userChoicesCountry.contains(choice.value.country) { | |
83 userChoices[choice.key] = choice.value | |
84 } | |
85 } else { | |
86 fatalError("Couldn't get a random value from data") | |
87 } | |
88 } | |
89 | |
90 // Get correct answer | |
91 let randomCityKeys = data.keys.shuffled() | |
92 let userChoicesCountry = userChoices.map { $0.value.country } | |
93 | |
94 let correctCityKey = randomCityKeys.first(where: { | |
95 !userChoices.keys.contains($0) && // Avoid duplicated cities | |
96 !dataAsked.keys.contains($0) && // Avoid cities already asked | |
97 !userChoicesCountry.contains(data[$0]!.country) // Avoid duplicated country names in userChoices | |
98 }) | |
99 | 72 |
100 // Unwrap optional | |
101 if let correctCityKey = correctCityKey { | |
102 let correctCityValue = data[correctCityKey]! | |
103 | |
104 userChoices[correctCityKey] = correctCityValue | |
105 dataAsked[correctCityKey] = correctCityValue | |
106 | |
107 let correctAnswer = (key: correctCityKey, value: correctCityValue) | |
108 self.correctAnswer = correctAnswer | |
109 } else { | |
110 fatalError("Couldn't unwrap optional value") | |
111 } | |
112 | |
113 self.userChoices = userChoices | |
114 } | |
115 } | |
116 |