Search code examples
swiftrandomgamekit

Setting seed of GKARC4RandomSource


I'm using GKARC4RandomSource (from GameKit) to generate random numbers. After setting my seed I generate some random numbers. On the same instance, but latter, I set the exact same seed and I'm generating again some numbers. Since the seed is the same I'm expecting the same numbers, but this does not happen. What is am I missing? Code:

let randSource = GKARC4RandomSource()

    func foo() {
        print("1st sequence")
        randSource.seed = "seed".data(using: .utf8)!
        for _ in 0...10 {
            print(randSource.nextInt())
        }
    }


    func bar() {
        print("2nd sequence")
        randSource.seed = "seed".data(using: .utf8)!
        for _ in 0...10 {
            print(randSource.nextInt())
        }
    }

    foo()
    bar()

Output: 1st sequence 1077893367 -527596564 188760480 -1473410833 1247450388 155479986 -1227640578 -1952625186 -1819582711 1494875350 238061911 2nd sequence -815382461 1319464721 -496336642 1307036859 -1543687700 1786062933 63740842 657867659 -1908618575 360960015 75414057


Solution

  • The documentation for GKARC4RandomSource suggests using the seed in the initializer.

    Any two random sources initialized with the same seed data will generate the same sequence of random numbers. To replicate the behavior of an existing GKARC4Random​Source instance, read that instance’s seed property and then create a new instance by passing the resulting data to the init(seed:​) initializer.

    If you use init(seed:), it works:

    func foo() {
        print("1st sequence")
    
        let seed = "seed".data(using: .utf8)!
        let randSource = GKARC4RandomSource(seed: seed)
        for _ in 0...10 {
            print(randSource.nextInt())
        }
    }
    
    
    func bar() {
        print("2nd sequence")
    
        let seed = "seed".data(using: .utf8)!
        let randSource = GKARC4RandomSource(seed: seed)
        for _ in 0...10 {
            print(randSource.nextInt())
        }
    }
    
    foo()
    bar()
    

    Output

    1st sequence
    -907495547
    -1853348607
    -891423934
    -1115481462
    -1946427034
    -1478051111
    1807292425
    525674909
    -1209007346
    -1508915292
    -1396618639
    2nd sequence
    -907495547
    -1853348607
    -891423934
    -1115481462
    -1946427034
    -1478051111
    1807292425
    525674909
    -1209007346
    -1508915292
    -1396618639