我的笔记里有不少感觉可以分享出来的东西,所以后面也会发点类似这个文章,虽然都比较简单,算是记录和分享一下吧
1. 使用 randomElement()
这种比较简洁也不需要计算索引,不过可能会返回空集合
也可以使用guard let 但通常用于提前退出方法或者函数,可以减少嵌套,使代码更加清晰

if let randomPlay = Play.allCases.randomElement() {
		// 使用 randomPlay
    print("Random play: \(randomPlay)")
} else {
    // 集合为空的情况,因为在Play为空时会返回nil
}
// 也可以不用if强制解包
let randomPlay = Play.allCases.randomElement()!

2. 使用 Int.random(in:) 生成随机索引
简洁易读,比较不错的实现方式

let allOptions = Play.allCases
let randomIndex = **Int.random(in: 0..<allOptions.count)**
let randomPlay = allOptions[randomIndex]
print("Random play: \(randomPlay)")

类似的还有Float.random(in:),Double.random(in:),Bool.random()等

3. 使用 RandomNumberGenerator
提供了更多的灵活性,可以使用不同的随机数生成器。
适合需要更高级随机数生成需求的场景

var rng = SystemRandomNumberGenerator()
let allOptions = Play.allCases
let randomIndex = Int(rng.next(upperBound: UInt(allOptions.count)))
let randomPlay = allOptions[randomIndex]
print("Random play: \(randomPlay)")

RandomNumberGenerator 是 Swift 中用于生成随机数的协议。SystemRandomNumberGenerator(系统自带的唯一一个) 是遵循该协议的一个类型,它使用系统的随机数生成器来生成随机数,也可以使用其他随机数生成器

由于灵活性,我们可以创建比如”更容易出石头的随机器”
比如这个70%的概率出石头的生成器

struct BiasedRandomNumberGenerator: RandomNumberGenerator {
    func next() -> UInt64 {
        // 生成一个 0 到 9 的随机数
        let randomValue = arc4random_uniform(10)
        
        // 70% 的概率返回 0(表示“石头”)
        if randomValue < 7 {
            return 0
        } else if randomValue < 9 {
            return 1
        } else {
            return 2
        }
    }
}

let biasedRNG = **BiasedRandomNumberGenerator()**
let allOptions = Play.allCases
let randomIndex = Int(biasedRNG.next() % UInt64(allOptions.count))
let randomPlay = allOptions[randomIndex]
print("Biased random play: \(randomPlay)")

或则我们可以做线性同余生成器(Linear Congruential Generator,LCG)来提供一个种子值来初始化这个生成器,以获得可重现的随机序列(提供一个种子获得可重复的结果)
这种伪随机数适用于需要可重现随机序列的场景,例如模拟、测试或游戏开发中的过程生成

struct LinearCongruentialGenerator: RandomNumberGenerator {
    private var state: UInt64
    
    init(seed: UInt64) {
        self.state = seed
    }
    
    mutating func next() -> UInt64 {
        state = 6364136223846793005 &* state &+ 1
        return state
    }
}

var lcg = LinearCongruentialGenerator(**seed**: 12345)
let randomValue = lcg.next()

4. 使用 arc4random_uniform()
如果要支持早期iOS的话可以用它

let allOptions = Play.allCases
let randomIndex = **Int(arc4random_uniform(UInt32(allOptions.count)))**
let randomPlay = allOptions[randomIndex]
print("Random play: \(randomPlay)")