When I was forced by a deadline into delivering this project, I noted in its post that there was a number of improvements to make:
- The rock paper scissors could be some better data structure than an array and some ints.
- I don’t love the try to win, try to lose aspect, but the client specified it
- Having the didUserWin and didComputerWin funcs is a cop out – that should probably be a single function returning a win/lose/draw type
- I also am unhappy with nesting them in the view namespace to use my #consts
- duplicating the last part of the view but making the elements .hidden() to keep the same spacing seems like a kludge
- when I added the link to the Hacking With SwiftUI page with the app brief just now, I noticed I haven’t done the scoring the way it was asked for
Here’s the progress
The rock paper scissors could be some better data structure than an array and some ints
Done. Made a sweet swifty enum. Read about it here. That also solved #4
I don’t love the try to win, try to lose aspect, but the client specified it
We can’t always help what a client wants. Deal with it.
_Having the didUserWin and didComputerWin funcs is a cop out – that should probably be a single function returning a win/lose/dra_w
enum GameResult {
case win
case loss
case draw
}
func gameResult(user: FingerShape, computer: FingerShape) -> GameResult {
switch user {
case .rock:
switch computer {
case .rock: return .draw
case .paper: return .loss
case .scissors: return .win
}
case .paper:
switch computer {
case .rock: return .win
case .paper: return .draw
case .scissors: return .loss
}
case .scissors:
switch computer {
case .rock: return .loss
case .paper: return .win
case .scissors: return .draw
}
}
}
duplicating the last part of the view but making the elements .hidden() to keep the same spacing seems like a kludge
This was an issue - not just because of the mess of code, but because (according to Paul) it’s a workload issue - the view managing part of SwiftUI has to keep creating and destroying parts of our view instead of recycling them. In an earlier lesson, he encouraged the use of the ternary operator in modifiers to avoid this - but .hidden() doesn’t have any arguments. Here’s the sort of code I’m talking about - I’ve got this sort of thing several places.
if revealResult {
Text(computerSelection.rawValue)
.font(.system(size: 200))
Text(winText).font(.title)
Spacer()
Button("Play again") {
goalIsWinThisTurn = Bool.random()
revealResult = false
if showScores {
score = 0
numberOfPlays = 0
showScores.toggle()
}
}
.buttonStyle(CustomButtonStyle())
}
else {
Text(computerSelection.rawValue)
.font(.system(size: 200))
.hidden()
Text(winText)
.font(.title)
.hidden()
Spacer()
Button("Play again") {}
.buttonStyle(CustomButtonStyle())
.hidden()
}
I was surprised when googling something like “swiftui view visibility not hidden()” I found, instead of a stack overflow question, a nice Apple tutorial at the top of the links.
Within was my answer - most views have an .opacity() modifier. With that, the code above becomes:
Group {
Text(computerSelection.rawValue)
.font(.system(size: 200))
Text(winText).font(.title)
Spacer()
Button("Play again") {
goalIsWinThisTurn = Bool.random()
revealResult = false
if showScores {
score = 0
numberOfPlays = 0
showScores.toggle()
}
}
.buttonStyle(CustomButtonStyle())
}
.opacity(revealResult ? 1 : 0)
Noice. I then when on a ternary insertion spree that dropped my view body down from 74 lines of code to 52 and improved readability substantially.