通过数字范围随机化

时间:2016-01-05 22:41:41

标签: swift random arc4random

我试图让应用程序的这一部分工作是用户点击一个按钮,标签打印一个1-12之间随机生成的数字。我已经能够成功地做到这一点,但我也希望它不会重复任何已经打印过的随机数。

我尝试过的是将任何打印的数字放入数组中,然后在每次生成新数字时检查数组。

我已经让它在Playground工作,但无法让它与真正的项目合作。

这是我项目的代码。

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

这是我操场上的代码。

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

3 个答案:

答案 0 :(得分:4)

系统已有一个工具:GKShuffledDistribution是GameplayKit中众多随机化实用程序之一。它与其他GKRandom类的不同之处正是你所要求的 - 它确保不重复已经被绘制的值#34;来自其随机池。

以下是一个例子:

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

使用游乐场绘制结果图表,您会注意到没有数字会立即重复(图中没有水平线),并且每12&#34;滚动&#34;不会重复多次。

如果您想自己实施类似的行为,可以通过使用SetDictionary<Int, Bool>之类的内容来改善您的其他尝试(以及迄今为止的其他答案)未使用的值,因为它们可以在不搜索整个数据结构的情况下响应contains

答案 1 :(得分:1)

另一种解决方案:

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

您可以使用可用数字数组开始绘制程序。然后通过绘制随机索引并从数组中删除所述索引处的元素来随机选择数组的元素。它会自动调整阵列的大小,并确保您不会再次绘制相同的数字。

答案 2 :(得分:0)

我不太清楚为什么你的代码不能正常工作,但尝试使用这段代码就行了。

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)

       }
}

<强>更新
usedNumbers.contains(randomConv)条件为true时,您可以使用此行再次触发按钮事件:btn_Pressed.sendActionsForControlEvents(.TouchUpInside) - btn_Pressed是您的故事板中的按钮插座。

我更新了代码块,以便您可以看到完整的示例。

更新2,替代解决方案

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