UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Project 2: Guess the Flag Upgrades

Forums > 100 Days of SwiftUI

@uh0h  

Hi all.

Working through Project 2 and added some features and wanted to ask about conventions, best practice, all of that since I'm totally new to programming and have no idea about the optimal way to do things. I feel I've done some things in a wacky way. If anyone could have a glance and give pointers, I'd be very appreciative.

There's custom fonts in here that won't load but other than that.

Here's my code:

import SwiftUI

let GTFOrange = (Color(red: 1, green: 0.39, blue: 0))
var leaderboard: [String] = ["0", "0", "0", "0", "0"]

struct ContentView: View {
    @State private var scoreAmount = 0
    @State private var countries = ["Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Russia", "Spain", "UK", "US"].shuffled().shuffled()
    @State private var correctAnswer = Int.random(in: 0...2)
    @State private var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State private var elapsedTime = 0.0
    var roundedTime : String { return String(format:"%.f", elapsedTime) }
    @State private var showingAlert = false

    var body: some View {
        ZStack{
            Color(GTFOrange)
                .ignoresSafeArea()
            VStack {
                VStack {
                    Text("tap the flag of")
                    Text(countries[correctAnswer])
                        .font(Font.custom("HUN-din 1451", size: 60))
                        .padding(.top)
                        .textCase(.uppercase)
                }
                ZStack {
                    Rectangle()
                        .fill(Color(red: 0.85, green: 0.85, blue: 0.85))
                        .frame(width: 250, height: 405)
                        .clipShape(RoundedRectangle(cornerSize: CGSize(width: 20.0, height: 20.0)))
                        .shadow(radius: 5)
                    VStack {
                        ForEach(0..<3) { number in
                            Button {
                                flagTapped(number)
                                startTimer()
                                youWin()
                            } label: {
                                Image(countries[number])
                                    .renderingMode(.original)
                                    .padding(10)
                                    .shadow(radius: 10)
                            }.onReceive(timer) { _ in
                                if scoreAmount > 0 {
                                    elapsedTime += 0.333333333333333
                                }
                            }
                        }.alert("Time taken", isPresented: $showingAlert) {
                        } message: {
                        Text("You took \(leaderboard[0]) seconds to get all the flags right!")
                        }
                    }
                }
                Text("Time: \(roundedTime)")
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.top)

                Text("times")

                Text(leaderboardPrinter())
                    .frame(maxWidth: .infinity, alignment: .center)
                    .font(Font.custom("HUN-din 1451", size: 30))
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .bottom)
        }
        .font(Font.custom("HUN-din 1451", size: 30))
        .foregroundStyle(Color.white)
    }
    func flagTapped(_ number: Int) {
        if number == correctAnswer {
            scoreAmount += 1
            countries.shuffle()
            correctAnswer = Int.random(in: 0...2)
        } else {
            scoreAmount = 0
            countries.shuffle()
            correctAnswer = Int.random(in: 0...2)
            stopTimer()
        }
    }
    func youWin() {
        if scoreAmount == 10 {
            showingAlert = true
            scoreAmount = 0
            countries.shuffle()
            correctAnswer = Int.random(in: 0...2)
            stopTimer()
        }
    }
    func startTimer() {
        self.timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    }
    func stopTimer() {
        leaderboard.insert(String(roundedTime), at: 0)
        self.timer.upstream.connect().cancel()
        elapsedTime = 0.0
    }
    func leaderboardPrinter() -> String {
        if leaderboard.isEmpty {
            return "-"
        } else if leaderboard.count > 5 {
            leaderboard.removeLast()
            return leaderboard.joined(separator: " - ")
        } else {
            return leaderboard.joined(separator: " - ")
        }
    }
}

#Preview {
    ContentView()
}

Thanks!

2      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.