In this mobile Rock, Paper, Scissors game I'm developing, I expect to have specific Image and Text Views populate to represent the user's and computer's move. So far, the correct Image and Text View appears for the user but not for the computer. The logic is sound, as I've used multiple print statements to check to see if the details for a randomly selected enum case are all the same but for some reason, the Image and Text View differ from the computer's move. I'm too new to really understand what is going on, can anyone offer an explanation so that I can come up with a solution? Please let me know if more information is needed.
struct PlayerVSComputerView: View {
var randomRawValue = Int.random(in: 0...2)
var body: some View {
NavigationView{
ZStack{
VStack{
let computerChoice = MoveOptionModel(rawValue: randomRawValue)!
MoveOptionIcon(moveImage: computerChoice.id.iconImage, moveTitle: computerChoice.id.iconTitle)
HStack{
// other Views
}// HStack End
.onAppear {
print("Raw Value: \(randomRawValue), Computer Choice: \(computerChoice), Icon Title: \(computerChoice.id.iconTitle), ID: \(computerChoice.id)")
}
}// VStack End
}// ZStack End
}// NavigationView End
}// body End
}
enum MoveOptionModel: Int, CaseIterable, Identifiable {
case rock = 0
case paper = 1
case scissors = 2
var id: MoveOptionModel { self }
var iconImage: ImageResource {
switch self {
case .rock:
.rock
case .paper:
.paper
case .scissors:
.scissors
}
}
var iconTitle: String {
switch self {
case .rock:
"Rock"
case .paper:
"Paper"
case .scissors:
"Scissors"
}
}
}
struct MoveOptionIcon: View {
let moveImage: ImageResource
let moveTitle: String
var body: some View {
VStack{
Image(moveImage)
.resizable()
.scaledToFit()
.frame(height: 100)
Text(moveTitle)
.font(.title)
.italic()
.foregroundStyle(.black)
}
.padding(10)
}
}
The solution is to turn randomValue into a State property. I also created a button to run again the random assignment. I am not sure why you need it to be identifiable, but in this case, I removed the protocol and id.
struct PlayerVSComputerView: View {
@State var randomRawValue = Int.random(in: 0...2)
var body: some View {
NavigationView{
ZStack{
VStack{
let computerChoice = MoveOptionModel(rawValue: randomRawValue)!
MoveOptionIcon(moveImage: computerChoice.iconImage, moveTitle: computerChoice.iconTitle)
Button("Play Again") {
var newRandomRawValue = Int.random(in: 0...2)
while newRandomRawValue == randomRawValue {
newRandomRawValue = Int.random(in: 0...2)
// Ensure the new random value is different from the previous one
}
randomRawValue = newRandomRawValue
}
.onAppear {
print("Raw Value: \(randomRawValue), Computer Choice: \(computerChoice), Icon Title: \(computerChoice.iconTitle), Case: \(computerChoice)")
}
}// VStack End
}// ZStack End
}// NavigationView End
}// body End
}
enum MoveOptionModel: Int, CaseIterable {
case rock = 0
case paper = 1
case scissors = 2
var iconImage: ImageResource {
switch self {
case .rock:
.rock
case .paper:
.paper
case .scissors:
.scissors
}
}
var iconTitle: String {
switch self {
case .rock:
"Rock"
case .paper:
"Paper"
case .scissors:
"Scissors"
}
}
}
struct MoveOptionIcon: View {
let moveImage: ImageResource
let moveTitle: String
var body: some View {
VStack{
Image(moveImage)
.resizable()
.scaledToFit()
.frame(height: 100)
Text(moveTitle)
.font(.title)
.italic()
.foregroundStyle(.black)
}
.padding(10)
}
}