我的笔记里有不少感觉可以分享出来的东西,所以后面也会发点类似这个文章,虽然都比较简单,算是记录和分享一下吧
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)")