I tried to generate an array with strings in random order, but always got the error "Thread1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" at the end of function randomPile. Below is my code:
import UIKit
class RandomView: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var cardOrder = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing" ]
// cannot randomlize due to the lanuage drawbacks.
cardOrder = randomPile(cardOrder)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// random the order of the original card pile
func randomPile(arrayPile: String[]) -> String[] {
var arry = arrayPile
for( var i = arry.count-1; i > 0; --i){
var r = Int(arc4random())%(i+1)
var a = arry[r]
arry[r] = arry[i]
arry[i] = a
}
return arry
}
}
Also not an answer, because I can also run in playground and so I don't know where your problem is coming in. However, there's no need to create a new reference to the array and return it. I also implemented a Fisher-Yates shuffle variant which is geared towards an integer PRNG that excludes its upper bound, as arc4random_uniform
does:
func randomPile(myArray: String[]) -> Void {
for i in 0..(myArray.count - 1) {
let j = Int(arc4random_uniform(UInt32(myArray.count - i))) + i
let tmp = myArray[i]
myArray[i] = myArray[j]
myArray[j] = tmp
}
}
let cardOrder: String[] = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing" ]
println(cardOrder)
randomPile(cardOrder)
println(cardOrder)
After invoking this on your array, it's shuffled, no need for reassignment to cardOrder
.
Addendum - I just checked, and since cardOrder
doesn't appear again on the left of an assignment it can be declared with let
.
You can also make the shuffle capability generic, so why not?
func shuffle<T>(myArray: T[]) -> Void {
for i in 0..(myArray.count - 1) {
let j = Int(arc4random_uniform(UInt32(myArray.count - i))) + i
let tmp:T = myArray[i]
myArray[i] = myArray[j]
myArray[j] = tmp
}
}
let cardOrder: String[] = ["HeartSix","HeartNine", "ClubQueen", "SpadeKing"]
println(cardOrder) // [HeartSix, HeartNine, ClubQueen, SpadeKing]
shuffle(cardOrder)
println(cardOrder) // sample result: [SpadeKing, HeartNine, HeartSix, ClubQueen]
let intValues = [1,2,3,4,5,6,7,8,9,10]
println(intValues) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
shuffle(intValues)
println(intValues) // sample result: [3, 10, 8, 4, 9, 7, 1, 2, 5, 6]