1

I'm new to all of this so I hope this makes sense. I want to display random images when a button is pressed without having the same image appear twice in a row. I have found similar question on this site with answers that have helped, but I am still getting errors in my code that I do not understand.

Here is the code for my image array at the top under the class:

var imageArray:[String] = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"]

Here is the code I am using for the random numbers under the button IBAction: (there are probably mistakes in this I'm not aware of, like I said earlier I am a noob)

 var currentNo: UInt32 = 0

    func randomNumber(maximum: UInt32) -> Int {

        var randomNumber: UInt32

        do {
            randomNumber = (arc4random_uniform(6))
        }while currentNo == randomNumber

        currentNo = randomNumber

        return Int(randomNumber)
    }
    var imageString:String = self.imageArray [randomNumber]

    self.iPhoneImage.image = UIImage(named: imageString)

I'm getting an error on this line:

var imageString:String = self.imageArray [randomNumber]

It says

"Cannot subscribe value of type '[String]' with an index of type '(UInt32) -> Int'

2
  • You are calling the method without parameter - var imageString:String = self.imageArray [randomNumber]. Commented Jun 27, 2015 at 5:55
  • randomNumber method expects a parameter. Commented Jun 27, 2015 at 5:56

3 Answers 3

1

If you don't want the random item to repeat you can remove it and append it back after the next draw as follow:

var imageArray: [String] = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"]
var random: Int {
    return Int(arc4random_uniform(UInt32(imageArray.count)))
}
var lastImage = ""
var imageName: String {
    let newImage = imageArray.removeAtIndex(random)
    if lastImage != "" {
        imageArray.append(lastImage)
    }
    lastImage = newImage
    return newImage
}

Testing

println(imageName)  // "ofCourse"
println(imageName)  // "no"
println(imageName)  // "yes"
println(imageName)  // "nope"
println(imageName)  // "indeed"
println(imageName)  // "noWay" 
println(imageName)  // "ofCourse"
println(imageName)  // "noWay
println(imageName)  // "nope"
println(imageName)  // "ofCourse"
println(imageName)  // "noWay"
println(imageName)  // "yes"
println(imageName)  // "ofCourse"
println(imageName)  // "indeed"
println(imageName)  // "yes"
println(imageName)  // "nope"
println(imageName)  // "noWay"
println(imageName)  // "no"
println(imageName)  // "noWay"
Sign up to request clarification or add additional context in comments.

7 Comments

yes this way it will not repeat.Great logic Leo..:)
I ran your code and ended it with self.iPhoneImage.image = UIImage(named:imageName) But it will still occasionally use the same image twice in a row! Any idea what's going on?
I am pretty sure you are not running my code as it is. It removes the last element so there is no way to get repeated
Is this right? var imageArray:[String] = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"] var random:Int{ return Int(arc4random_uniform(UInt32(imageArray.count))) } var lastImage = "" var newImage = "" var imageName: String { newImage = imageArray.removeAtIndex(random) if lastImage != "" { imageArray.append(lastImage) } lastImage = newImage return newImage }
It works perfectly! I was putting the code in the wrong spot. Thanks!
|
0

This will work fine:

var imageString:String = self.imageArray[randomNumber(6)]

As you can see in your function declaration func randomNumber(maximum: UInt32) -> Int which means your function accept an argument maximum which is type of UInt32 and return Int.

But you are using your function like self.imageArray[randomNumber] where you want to access an element from imageArray with randomNumber function.

But your function accepts parameter which you doesn't assign so you can use your function this way randomNumber(6) where 6 is a max value.

And you can change your max value as per your need.

1 Comment

Thanks! That got rid of the error and ran, but there are still Images that are appearing twice in a row. Do you know what the problem might be?
0

With GameKit there is actually a built in random distribution that does this for you while still being uniform and pretty random:

import GameplayKit

let imageArray = ["yes", "no", "indeed", "nope", "ofCourse", "noWay"]

let randomDistribution = GKShuffledDistribution(lowestValue: 0, highestValue: imageArray.count - 1)

func randomItem() -> String {
    return imageArray[randomDistribution.nextInt()]
}

I suggest encapsulating this into its own type:

struct RandomNonRepeating<Element> {
    let values : [Element]
    let distribution : GKRandomDistribution

    init(values : [Element]) {
        self.values = values
        distribution = GKShuffledDistribution(
            lowestValue: 0, highestValue: values.count - 1)
    }

    func next() -> Element {
        return values[distribution.nextInt()]
    }
}

which can be used like this:

let x = RandomNonRepeating(values: [1, 2, 3, 4, 5])

for _ in 0...30 {
    x.next()
}

gives

4
3
2
1
5
2
4
3
1
5
4
3
2
1
5
3
1
2
4
5
4
1
3
2
5
4
3
1
2
5
3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.