War card game deal mod for number of cards

Hello, can anyone please help me understand why sometimes this code makes 1 or 2 cards get dealt, the code is copied from the war card game and it should (as far as i understand always deal 3 cards, i mean why would it mostly deal 3 and sometimes “decide” to deal 2 or 1?
code:
struct ContentView: View {

@State private var card1 = "card14"
@State private var card2 = "card14"
@State private var card3 = "card14"

@State var bet = 0
@State var win = 0

var body: some View {
    ZStack {
        Image ("background").ignoresSafeArea()
        
        VStack {
            
            Group{
           
                Image("ptc").resizable().aspectRatio(contentMode: .fit).frame(width: 300.0, height: 70.0)
                
                HStack {
                    
                    Image(card1)
                    Image(card2)
                    Image(card3)
                }
                HStack {
                    Spacer()
                    VStack {
                        Text("Bet")
                            .font(.headline)
                            .foregroundColor(Color.white)
                        Text(String(bet))
                            .font(.largeTitle)
                            .foregroundColor(Color.white)
                    }
                    Spacer()
                    VStack {
                        Text("Win")
                            .font(.headline)
                            .foregroundColor(Color.white)
                        Text(String(win))
                            .font(.largeTitle)
                            .foregroundColor(Color.white)
                    }
                    Spacer()
                }
            }
            
            
          
            Group{
                
                Image("numbers").resizable().frame(width: 400.0, height: 180.0)
                
                Text("Pairs +")
                
                Button(action:{
                    
                    // Generate a random number between 2 and 14
                    let card1Rand = Int.random(in: 2...14)
                    let card2Rand = Int.random(in: 2...14)
                    let card3Rand = Int.random(in: 2...14)
                    
                    // Update cards
                    card1 = "card" + String(card1Rand)
                    card2 = "card" + String(card2Rand)
                    card3 = "card" + String(card3Rand)
                    
                }, label: {Image("deal_button").resizable().frame(width: 150.0, height: 70.0)
                    
                })
                
            }
            
            HStack {
                
                Group{
                    Button(action:{}, label: {Image("25_chip").resizable().frame(width: 80.0, height: 90.0)
                        
                    })
                    Button(action:{}, label: {Image("100_chip").resizable().frame(width: 80.0, height: 90.0)
                        
                    })
                    
                    Button(action:{}, label: {Image("500_chip").resizable().frame(width: 80.0, height: 90.0)
                        
                    })
                    
                    Button(action:{}, label: {Image("1k_chip").resizable().frame(width: 80.0, height: 90.0)
                        
                    })
                }
               
            }
            
        }
        
    }
}

}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

I assume that you think the card is not new, because the card does not change, although the card is in fact new.

If (for example) the card1Rand ist an integer of 4 and the next time the random number is also a 4, nothing will change for your card1. You could verify this by adding a breakpoint or a print statement and have a look in the simulator.
If you want to force another card, you would need to compare the current to the new card and if equal, shuffle again till the cards are not equal anymore.

hi Wildsparrow, thank you for looking at this. When you say not new you mean the same card appears, if so I get that and that’s fine or do you mean this is the reason for less than 3 cards appearing? I got the code for that part from Chris’s war card game, where 2 card always appear, so why aren’t 3 cards appearing? The issue though is that sometimes only 2 or even 1 card will appear. Are you able to help with the code for forcing 3 cards?

Hi.

So, as I said, your cards are indeed always shuffled.
But when the card1 was (for example) a king of spades and the newly shuffled card was again the king of spades, you will still see the king of spades and “nothing” changed.

If you don’t want that but have always a new (different) card, you would need to shuffle the cards as long as the new card is not equal to the old card. For that, you could use the while loop. "While the new card ist the same as the old one, shuffle again. " Once the new card is different to the old one, you update the card.

This is my code which replaces your code in the Button for the action closure. I wanted to keep as much of your code and just update the part for the card comparison. Note: I needed to change the let card1Rand to a var card1Rand, as the card1Rand will be updated (which is only possible with a var variable, not a let constant). I also included some print statements, so you can check when there was an equal card and was shuffled again (you will only see that in the simulator, not in the canvas.) I only did that for the card3.

// Generate a random number between 2 and 14
                        var card1Rand = Int.random(in: 2...14)
                        var card2Rand = Int.random(in: 2...14)
                        var card3Rand = Int.random(in: 2...14)
                        
                        // check if new random card 1 is equal to card1. If so, create a new random card 1
                        
                        while "card" + String(card1Rand) == card1 {
                            card1Rand = Int.random(in: 2...14)
                        }
                        
                        // When the new random card 1 is not equal to card1, the while loop will exit and the new card1 is set
                        card1 = "card" + String(card1Rand)
                        

                        // Repeat for the other two cards
                        while "card" + String(card2Rand) == card2 {
                            card2Rand = Int.random(in: 2...14)
                        }
                        card2 = "card" + String(card2Rand)
                       
                        while "card" + String(card3Rand) == card3 {
                            card3Rand = Int.random(in: 2...14)
                            print("Card three was equal to former card three. The card was shuffled again.")
                        }
                        card3 = "card" + String(card3Rand)
                        print("Card three was not equal to former card three")

Thank you so much for your help and the explanation, does this mean though that if, for example, we dealt three king of spades in round one we can still get three king of spades in round two? I mean it should be random so getting the same cards in consecutive rounds should be possible.

In your original code it is technically possible and it even has the same probability than any other combination of cards (though this is counterintuitive).

thanks Wildsparrow; so is it possible in your code? I need it to be possible because I want the cards to be random and so don’t want any restriction on what the card could be. I just want 3 random cards dealt each round that may (or may not) be the same cards as the previous round, does your code do that?

Just to be on the same page:
When I run your code, there are always 3 cards displayed. When I hit the deal button, the cards get updated. There are always 3 cards displayed. There are never only 2 or 1 card displayed and the remaining space is not empty (where a card should be).

I understood that your issue is that sometimes there are three cards (let’s say heart 2, heart 3, heart 4), you hit the deal button and not all of them get updated, so after dealing there could be heart 2 (again), spades 5, spades 6.
In that case, the heart 2 was indeed updated, but as there was already a heart 2, there is still a heart 2 and visually nothing changed.

Thus I suggested to shuffle the cards as long as the new card is not equal to the former card. But this would be a restriction, as of 13 possible cards, only 12 could be the next card.

Now, with your latest question, I think I misunderstood you. I think now, that when you run your code, sometime you hit the deal button and only 2 (or 1) card is visible. The space of the missing card(s) is just empty.
If this is true, then you have a typo in your card names in your asset folder, or one card is missing (you may not copied it or you may have accidentally deleted it).

Thank you so much for your help, I really appreciate it! You got it, the card2 name was card 2 in the assets. So stupid of me, thank you so so much!

1 Like