1

I do realize similar questions have been asked before, I looked at them before seeking help. But they were either not in Swift or too complex for me to decipher. My question is different from How do I shuffle an array in Swift? in that I have already done some of the work, like shuffling. The title was actually different from the question asked, which was "How do I randomize or shuffle the elements within an array in Swift?" I am only interested in iterating the resulting array and I couldn't separate that part from the rest of the code in the answers given for a question that encompassed so much more. That said, there are some great suggestions on that page so I think people like me will benefit from having both pages available. Maybe someone can set up a reciprocal link on that page as I have done here.

Admittedly, I am new to Swift and not a seasoned programmer in any language, but please don't assume I am coming here seeking help without trying to figure it out on my own. I am spending many hours learning the fundamentals of all C based languages and reading the Swift literature at developer.apple.com.

So the question will be more obvious, I and attempting to build the card game War. Thus far I have accomplished constructing the (an array) deck of cards and randomized it (shuffled). I am stuck at looping through the resulting array of 52 objects and assigning (moving) them to the two players hands (two new arrays). I'm not sure how much of my code I should display in order to help me but if you need more, I'll gladly provide it. Please note that this is only an exercise, practice for me to learn how to write complex programs, and some code, like the function to randomize, is not mine, I found it right here at stackoverflow. I'd almost prefer if you didn't just hand me the code that will work, I'm not likely going to learn as much that way, but if providing steps in plain English so I can figure out the syntax is too much trouble, so be it, provide an example, I'm sure I'll get plenty of chances to write/use the syntax later.

One more note, I'm only working in a playground at the moment, when and if I can get all the code working, I'll move to the UI stuff.

Thanks in advance, Rick

/* Skipping past everything I did to get here, 
the array (shuffledDeck) has 52 shuffled cards (elements) in it. 
The array is NSMutableArray and contains strings like 
2Hearts, 5Spades, 14Clubs, etc. Each suit has 14 cards.*/

shuffledDeck

// create vars to hold shuffled hands
var playerOneHand = []
var playerTwoHand = []

/* Started a for loop to assign cards to each hand 
but don't know which method(s) is/are best to use 
to remove the first or last card and alternately 
append (move) it to the (hopefully) initialized 
variables playerOneHand and PlayerTwoHand. 
Optionally, since the cards are already shuffled, 
I could just split the deck using the range method, 
whichever is easier. I tried and failed at both ways.*/

var i = 0
for dealtCard in shuffledDeck {

}
Community
  • 1
  • 1
Rick_P
  • 96
  • 1
  • 7
  • 2
    If the array is randomly shuffled then you might as well assign the first 26 cards to player 1 and the remaining 26 cards to player 2. – OK you tried that already. – Martin R May 02 '15 at 20:05
  • Given the whole point is to learn, I'd love to see how to use both methods if anyone is up for demonstrating how to use the range method to move half of shuffledDeck into firstPlayerHand and the other half into secondPlayerHand. – Rick_P May 02 '15 at 20:21
  • I wrote a working War game (just text, no GUI) for Swift 4.0 as an OOP example for my students if anyone is interested. – adazacom Dec 10 '18 at 10:18

2 Answers2

2
var shuffledDeck:[String] = ["2Hearts", "5Spades", "14Clubs", "etc"]
//shuffledDeck will of course be your shuffled deck
var playerOneHand:[String] = []
var playerTwoHand:[String] = []

for (index, cardString) in enumerate(shuffledDeck) {
    if index % 2 == 0 {
        playerOneHand.append(cardString)
    }else{
        playerTwoHand.append(cardString)
    }
}

I’m looping through every item in the shuffledDeck, but with that I use the index of the array to get a number. I use this number to see if that number devided by 2 is equal to 0 (the number is even) or not (uneven) if a number is even, I get the item that is in the array at the given index and add that item to the hand of player one. If the index is uneven I add the item to the second player’s hand. This means the first item goed to player one’s hand, the second item goes to the hand of the second player. the third Item goes back to the first player and so on.

milo526
  • 5,012
  • 5
  • 41
  • 60
  • The second bit is perfect, but the first bit creates an array shuffledDeck which contains the cards in order (most definitely **not** shuffled.) – Duncan C May 02 '15 at 20:07
  • Yeah I posted the code I used to check if the loop does indeed split it evenly, updated the code (and included string’s instead of ints as OP stated in question) – milo526 May 02 '15 at 20:08
  • I see you changed your answer right after I posted my comment. You might want to add a "//Code to build the shuffled deck goes here" comment in your code. – Duncan C May 02 '15 at 20:09
  • Thank you Milo and everyone who chimed in. Milo, I'm getting an error ('AnyObject is not convertible to 'String') in Playground for both playerOneHand.append(cardString), and playerTwoHand.append(cardString) . Any suggestions? – Rick_P May 02 '15 at 20:52
  • you need to declare your array as :[String] – Leo Dabus May 02 '15 at 20:53
  • Leonardo, I'm not clear how to fix this. shuffledDeck is an NSMutableArray so I don't think I can down cast that, or don't know how anyway, and playerOneHand and playerTwoHand are String arrays. It's not terribly important that I figure this out because you have already provided a solution below, but if it's not too complicated to correct I'd like to see it work. – Rick_P May 02 '15 at 23:56
1

As mentioned by Martin R you can use the range method to assign the first half of the deck to the first player and the second to the second player as follow:

let cards:[String] = ["2♦️","3♦️","4♦️","5♦️","6♦️","7♦️","8♦️","9♦️","T♦️","J♦️","Q♦️","K♦️","A♦️","2♠️","3♠️","4♠️","5♠️","6♠️","7♠️","8♠️","9♠️","T♠️","J♠️","Q♠️","K♠️","A♠️","2♥️","3♥️","4♥️","5♥️","6♥️","7♥️","8♥️","9♥️","T♥️","J♥️","Q♥️","K♥️","A♥️","2♣️","3♣️","4♣️","5♣️","6♣️","7♣️","8♣️","9♣️","T♣️","J♣️","Q♣️","K♣️","A♣️"]

extension Array {
    var shuffled:[T] {
       var elements = self
        for index in 0..<elements.count - 1 {
            swap(&elements[index], &elements[Int(arc4random_uniform(UInt32(elements.count - 1 - index))) + index])
        }
        return elements
    }
}


let cardsShuffled = cards.shuffled

let playerOneHand = cardsShuffled[0...25]
let playerTwoHand = cardsShuffled[26...51]

Note: The shuffle extension was created using this answer as reference

Community
  • 1
  • 1
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Thanks Leonardo, this is fantastic. Two very interesting things happened. The cards had already been shuffled so now they have been shuffled twice. Better than Vegas! In addition, since Playground shows the contents of an array, I can see that each card's suit and value are separate now like an array of tuples, and the values appear to be integers. I find that interesting because they started out like that but I concatenated them thinking it would simplify shuffling and dealing. It's actually better this way, it will be easier to compare each draw to determine the winner of each hand. Sweet. – Rick_P May 02 '15 at 21:35