Swift 4.2+ seeding a random number generator

前端 未结 4 766
萌比男神i
萌比男神i 2021-02-13 17:19

I\'m trying to generate seeded random numbers with Swift 4.2+, with the Int.random() function, however there is no given implementation that allows for the random n

4条回答
  •  忘了有多久
    2021-02-13 17:33

    So I used Martin R's suggestion to use GamePlayKit's GKMersenneTwisterRandomSource to make a class that conformed to the RandomNumberGenerator protocol, which I was able to use an instance of in functions like Int.random():

    import GameplayKit
    
    class SeededGenerator: RandomNumberGenerator {
        let seed: UInt64
        private let generator: GKMersenneTwisterRandomSource
        convenience init() {
            self.init(seed: 0)
        }
        init(seed: UInt64) {
            self.seed = seed
            generator = GKMersenneTwisterRandomSource(seed: seed)
        }
        func next(upperBound: T) -> T where T : FixedWidthInteger, T : UnsignedInteger {
            return T(abs(generator.nextInt(upperBound: Int(upperBound))))
        }
        func next() -> T where T : FixedWidthInteger, T : UnsignedInteger {
            return T(abs(generator.nextInt()))
        }
    }
    

    Usage:

    // Make a random seed and store in a database
    let seed = UInt64.random(in: UInt64.min ... UInt64.max)
    var generator = Generator(seed: seed)
    // Or if you just need the seeding ability for testing,
    // var generator = Generator()
    // uses a default seed of 0
    
    let chars = ['a','b','c','d','e','f']
    let randomChar = chars.randomElement(using: &generator)
    let randomInt = Int.random(in: 0 ..< 1000, using: &generator)
    // etc.
    

    This gave me the flexibility and easy implementation that I needed by combining the seeding functionality of GKMersenneTwisterRandomSource and the simplicity of the standard library's random functions (like .randomElement() for arrays and .random() for Int, Bool, Double, etc.)

提交回复
热议问题