Randomizing through number range

本秂侑毒 提交于 2019-12-06 06:23:43

I´m not quite sure why your code is not working, but try this code instead this works.

var usedNumbers = [Int]()
var randomConv = 0

@IBAction func btnRandomPressed(sender: AnyObject) {
     randomConv = Int(arc4random_uniform(12) + 1)

        if usedNumbers.contains(randomConv) {
            // If you find a duplicate you fire the event again and a new number will be randomized
            print("Exists \(randomConv)")
            btn_Pressed.sendActionsForControlEvents(.TouchUpInside)

        } else {
            print(randomConv)
            lblTest.text = String(randomConv)
            usedNumbers.append(randomConv)

       }
}

Update
When the usedNumbers.contains(randomConv) condition is true, you can use this row to fire the button event again: btn_Pressed.sendActionsForControlEvents(.TouchUpInside) - btn_Pressed is your buttons outlet from your Storyboard.

I have updated the code block so that you can see a fully working example.

Update 2, An alternative solution

func randomize(){
    repeat {
        if (usedNumbers.count == 12){
            return
        }
        randomConv = Int(arc4random_uniform(12) + 1)
    } while usedNumbers.contains(randomConv)

    usedNumbers.append(randomConv)
    lblTest.text = String(randomConv)
}

@IBAction func btnRandomPressed(sender: AnyObject) {
     randomize()
}

The system already has a tool for this: GKShuffledDistribution is one of the many randomization utilities in GameplayKit. The one thing it does differently from other GKRandom classes is exactly what you ask — it makes sure not to repeat values that have already been "drawn" from its random pool.

Here's an example:

import GameplayKit
let shuffle = GKShuffledDistribution(forDieWithSideCount: 12)
for _ in 1...100 { print(shuffle.nextInt()) }

Use a playground to graph the results and you'll notice that no number ever repeats immediately (no horizontal lines in the graph) and also that no number repeats more than once every 12 "rolls".

If you wanted to implement similar behavior yourself, you could improve over your other attempts (and the other answers thus far) by using something like Set or Dictionary<Int, Bool> to store already-used or yet-unused values, as those can respond to contains without searching the entire data structure.

Another solution:

var availableNumbers = Array(1...12)
var randomConv = 0    

@IBAction func btnRandomPressed(sender: AnyObject) {
    if availableNumbers.count > 0 {
        let randIndex = Int(arc4random_uniform(UInt32(availableNumbers.count)))
        randomConv = availableNumbers.removeAtIndex(randIndex)

        someLabel.text = "\(randomConv)"
    }
}

You begin your program with array of available numbers to draw. Then you choose element of the array randomly by drawing random index and removing the element at said index from the array. It automatically resizes your array and you are sure that you won't draw the same number again.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!