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

Day 25 challenge - is there anything superfluous here?

Forums > 100 Days of SwiftUI

No two ways about it, I loved this challenge! I completed it without looking at the hints, so didn't use Paul's suggestion of a 'winning moves' array.

I implemented a 'correct answer' computed property (and also included the answer in a text field so I could test my logic - it can be commented out!) which feels a little cumbersome. Is there anything about the way I wrote that computed property which could be made... prettier?

Something that definitely could be prettier is... well all of the design. I haven't leaned into design yet! But I'm happy to have completed the challenge.

struct ContentView: View {

    // Properties
    let choices = ["πŸͺ¨", "πŸ“ƒ", "βœ‚"]

    // State properties
    @State private var score = 0
    @State private var appChoice = "πŸͺ¨"
    @State private var shouldWin = Bool.random()

    // computed properties
// computed property logic for whether or not the user's choice is correct
    var correctReponse: String {
        var answer: String {
                if appChoice == "πŸͺ¨" {
                return shouldWin ? "πŸ“ƒ" : "βœ‚"
            } else if appChoice == "πŸ“ƒ" {
                return shouldWin ? "βœ‚" : "πŸͺ¨"
            } else {
                return shouldWin ? "πŸͺ¨" :"πŸ“ƒ"
            }
        }

        return answer
    }

    // body
    var body: some View {
        NavigationView {
            ZStack {
                LinearGradient(colors: [.white, .gray],
                               startPoint: .top,
                               endPoint: .bottom)
                .ignoresSafeArea()

                VStack {

                    Spacer()

                    VStack {
                            Text("Current score: \(score)")
                    }

                    Spacer()

                    VStack {
                            Text("We chose: \(appChoice)")
                            Text("You should: \(shouldWin ? "WIN" : "LOSE")")
                            Text("Correct response: \(correctReponse)")
                    }

                    Spacer()
                    Spacer()
                    Spacer()

                    VStack {
                        Text("CHOOSE!")
                    }

                    HStack {
                        ForEach(choices, id: \.self) { choice in
                            Button {
                                buttonPressed(choice)
                            } label: {
                                Text("\(choice)")
                                    .font(.system(size: 75))
                            }
                        }
                    }

                    Spacer()

                }
            }
            .navigationTitle("Rock paper scissors brain trainer!")
            .navigationBarTitleDisplayMode(.inline)
        }
    }

    // functions
    func buttonPressed(_ chosen: String) {
        if chosen == correctReponse {
            score += 1
        } else {
            score -= 1
        }
        shouldWin.toggle()
        appChoice = choices[Int.random(in: 0...2)]
    }
}

2      

You could have made it tidier using a switch statement. I have kept your symbols and basic approach.

var correctReponse: String {
    var answer: String {
        switch appChoice {
        case "πŸͺ¨": return shouldWin ? "πŸ“ƒ" : "βœ‚"
        case "πŸ“ƒ": return shouldWin ? "βœ‚" : "πŸͺ¨"
        default: return shouldWin ? "πŸͺ¨" :"πŸ“ƒ"
        }
    }
    return answer
}

Regarding the layout, you have used multiple Spacer() statements. A similar layout can be achieved with padding. I have used literal constant values (100, 300, etc.) fo r an iPhaone 130 Pro Max layout. In practice these values would usually be replaced by computed values so that the layout can adapt to screen sizes. But here they are fixed.

var body: some View {
    NavigationView {
        ZStack {
            LinearGradient(colors: [.white, .gray],
                           startPoint: .top,
                           endPoint: .bottom)
            .ignoresSafeArea()

            VStack {
                Text("Current score: \(score)")
                    .padding(.bottom, 100)

                VStack {
                    Text("We chose: \(appChoice)")
                    Text("You should: \(shouldWin ? "WIN" : "LOSE")")
                    Text("Correct response: \(correctReponse)")
                }
                .padding(.bottom, 300)

                Text("CHOOSE!")

                HStack {
                    ForEach(choices, id: \.self) { choice in
                        Button {
                            buttonPressed(choice)
                        } label: {
                            Text("\(choice)")
                                .font(.system(size: 75))
                        }
                    }
                }
                .padding(.bottom, 50)
            }
        }
        .navigationTitle("Rock paper scissors brain trainer!")
        .navigationBarTitleDisplayMode(.inline)
    }
}

2      

thanks for your time and code - i'll poke around with it!

2      

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 April 28th.

Click to save your free spot now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.