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