Randomizing through number range

老子叫甜甜 提交于 2019-12-22 18:29:07

问题


I'm trying to get this part of the app to work were the user clicks a button and a label prints a randomly generated number between 1-12. I've been able to successfully do that, but I also want it to not repeat any random numbers that have already been printed.

What I've tried doing is putting any printed number into an array, and then checking the array each time it generates a new number.

I've gotten it to work in the Playground, but cannot get it working with a real project.

Here is the code for my project.

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

func randomize() {
    lblRandom.text = "\(arc4random_uniform(12) + 1)"
    randomConv = Int(lblRandom.text!)!
}

@IBAction func btnRandomPressed(sender: AnyObject) {
    randomize()
    if usedNumbers.contains(randomConv) {       
        randomize()

    } else {    
        usedNumbers.append(randomConv)

    }

    if usedNumbers.count == 12 {
        btnRandom.hidden = true
    } 
}

And here is the code from my playground.

var lblRandom = "\(arc4random_uniform(12) + 1)"
var randomConv = 0
var usedNumbers = [Int]()

func randomize() {
lblRandom = "\(arc4random_uniform(12) + 1)"
randomConv = Int(lblRandom)!
}

repeat {
randomize()

if usedNumbers.contains(randomConv) {
    randomize()   
} else {
    usedNumbers.append(randomConv)
    print(lblRandom)
}

} while usedNumbers.count < 12

回答1:


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()
}



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/34622567/randomizing-through-number-range

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