LAST CHANCE: Save 50% on all my Swift books and bundles! >>

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!

3      

Hacking with Swift is sponsored by Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

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.