How to generate random numbers in swift ?

How to generate random number ins swift

We can generate random numbers in swift by one of these three methods :

  1. using the arc4random library
  2. using the default system random number generator SystemRandomNumberGenerator
  3. by using GamePlayKit classes that implement the GKRandom protocol

arc4random library

the arc4random library can be used to generate cryptographically secure random number . The random numbers are generated using the AES algorithm , this can be changed in the future .

the functions that we can use in the library are

arc4random() -> UInt32;
arc4random_uniform(_ upper_bound : UInt32 ) -> UInt32;

the first method will return a random number which is an unsigned 32 bit int . The second method will return a random number which is an unsigned 32 bit int , lower than the upper bound that is specified .

//using arc4random
let randomUi32:UInt32 = arc4random();
print("the generated random number is : \(randomUi32)");


//using arc4ramdon_uniform
let randomUi32Uniform = arc4random_uniform(1000);// random umber between 0 and 999
print("the generated random number is : \(randomUi32Uniform)");

SystemRandomNumberGenerator

The SystemRandomNumberGenerator is a structure that implement the RandomNumberGenerator protocol . The protocol specify methods that can be used to generate random numbers . They are

next() → UInt64
next<T>(upperBound: T) → T

The first method generate a random unsigned 64 bit integer , and the second method will generate a random number which is less than the upper bound that is specified . The algorithm that is used by the SystemRandomNumberGenerator is for now AES under apple platforms. This algorithm can be used to generate cryptographically secure random numbers .

var randomGenerator = SystemRandomNumberGenerator();

// generate a next UInt64 using the SystemRandomNumberGenerator
//A random number generated using the randomGenerator.next() : 10196746748631372535
print("A random number generated using the randomGenerator.next() : \(randomGenerator.next())")


// generate a random number which has an upper bound of 32767 which is Int16.max
//A random number generated using the randomGenerator.next(upperBound:) : 4160
print("A random number generated using the randomGenerator.next(upperBound:) : \(randomGenerator.next(upperBound : (UInt16)(Int16.max)))")

GamePlayKit GKRandom classes

GamePlayKit is a library that is created by apple which allow us to build and design a game. The library has tools that allow us to generate random numbers .

GKRandom

GKRandom is a protocol or an interface , which defines some methods. Classes that implement the GKRandom protocol , must implement these methods . These methods are used to generate random numbers.

The GKRandom protocol is implemented by all classes of the GamePlayKit framework that generate random numbers. Classes that implement this interface must implement the following methods :

nexInt() -> Int

generate a signed integer . an Int in swift will have 32 bit on a system that has 32 bit , and it will have 64 bit on a system that has 64 bit . As such on a system with 32 bit it has a min value of -2147483648 and a max value of 2147483647 , and on a system which has 64 bit it has a min value of -9223372036854775808 and a max value of 9223372036854775807

nextInt(upperBound: Int) → Int

generate a random integer which is less than the upper bound that is specified.

nextUniform() -> Float

generate a random float number

nextBool() -> Bool

generate a random boolean.

Classes that implement the GKRandom interface can be grouped into two groups .

  • those one that generate random numbers , so they are just a source of random numbers , and they don’t follow any distribution . These classes extends the GKRandomSource class which implements the GKRandom protocol
  • those one that generate random numbers from a source . The generated random numbers are distributed , which means that the generated random numbers will occur in a given probability , on the bounds where we are generating the random numbers .

Generating random numbers which don’t follow any distribution

GKRandomSource

the GKRandomSource class implement the GKRandom protocol , and is extended by all classes that generate random numbers which are not distributed in GamePlayKit.

initialiser

we have two initializer that we can use with the GKRandomSource class

init()
init(coder aDecoder: NSCoder)

The first initializer takes no argument , and it will create a random number generator , from a source , which is not specified . The generated random number from this source are deterministic , and they are not cryptographically secure . Since we didn’t use a seed , we cannot recreate the deterministic random numbers .

the second initializer will deserialize a random source from an NSCoder

methods

this Class implements GKRandom , as such it implements all the methods that are defined using GKRandom .

nextInt()→Int
nextInt(upperBound:Int)→Int
nextUniform()→FLoat
nextBool()→Bool

it also defines two methods

sharedRandom() → GKRandomSource

which returns a shared source of randomness . This shared source can be used by multiple functions or multiple classes . The default shared random source is an instance of the system’s underlying random source , which is the arc4random functions .

arrayByShufflingObjects(in array: [Any]) -> [Any])

which is used to shuffle an array. The algorithm which is used to shuffle the array is called the fisher-Yates shuffle , and the shuffle is not crypto secure .

methods usage example
import GameplayKit
 
/*
 create an instance of GKRandomSource
 */
let gKRandomSource : GKRandomSource = GKRandomSource();
/*generate a next Integer*/
print(gKRandomSource.nextInt());//1222748269
 
/*generate an next Integer less than an upperBound*/
print(gKRandomSource.nextInt(upperBound: 5)); //1
 
/*generate a next Boolean*/
print(gKRandomSource.nextBool()) // false
 
/*generate a next Float*/
print(gKRandomSource.nextUniform()) //0.13131566
 
/*use a shared random source*/
print(GKRandomSource.sharedRandom().nextInt())//209993353
 
/*shuffle an array*/
let array  = [0 , 1 , 2 , 3 , 4 , 5]
let shuffledArray = gKRandomSource.arrayByShufflingObjects(in:array)
print(shuffledArray)//[3, 0, 1, 2, 5, 4]

GKARC4RandomSource

This class extends the GKRandomSource class , as such it inherits all of its methods . GKARC4RandomSource can generate random numbers which are deterministic , but which are not cryptographically secure .

The algorithm used to generate random numbers is the RC4 algorithm . It is good for generating game play random numbers which are deterministic and not crypto secure.

We must drop the first 768 values that are generated , since the initial sequence is repeatable , and we can predict future random numbers from the initial sequence .

This class has the same methods of GKRandomSource . it defines one additional property .

var seed: Data

This property allow us to access the seed that is used to generate random numbers . We can create another instance from this class using the same seed , and we will get the same random number that are generated by the two instances .

GKARC4RandomSource also defines one additional initializer , which allows us to create an instance of GKARC4RandomSource from a seed.

init(seed: Data)
methods usage example
import GameplayKit


/*create an instance of GKARC4RandomSource
 using seed generated by GKARC4RandomSource
 */
let gKARC4RandomSource : GKARC4RandomSource  = GKARC4RandomSource() ;


//drop the first 768 values since they are not secure
gKARC4RandomSource.dropValues(768);

// generate a next random Integer using gKARC4RandomSource
print(gKARC4RandomSource.nextInt()); //481672643

//get the seed that is used by gKARC4RandomSource to generate random numbers
// the seed is a byte buffer in memory
let seedGKARC4RandomSource = gKARC4RandomSource.seed;

// create a GKARC4RandomSource instance from  a seed
// the seed  is the seed from the earlier gKARC4RandomSource instance
let gKARC4RandomSourceFromSeed : GKARC4RandomSource  = GKARC4RandomSource(seed: seedGKARC4RandomSource)

// drop the first 768 values since they are not secure
gKARC4RandomSourceFromSeed.dropValues(768);

// generate a next random Integer using gKARC4RandomSourceFromSeed
// its value will be the same value generated using gKARC4RandomSource.nextInt() method
// since we are generating deterministic random numbers
print(gKARC4RandomSourceFromSeed.nextInt());//481672643


/*generate an next Integer less than an upperBound using gKARC4RandomSource*/
print(gKARC4RandomSource.nextInt(upperBound: 8)); //4

/*generate an next Integer less than an upperBound using gKARC4RandomSourceFromSeed*/
print(gKARC4RandomSourceFromSeed.nextInt(upperBound: 8)); //4


/*generate a next Boolean using gKARC4RandomSource*/
print(gKARC4RandomSource.nextBool()) // false

/*generate a next Boolean using gKARC4RandomSourceFromSeed*/
print(gKARC4RandomSourceFromSeed.nextBool()) // false

/*generate a next Float using gKARC4RandomSource*/
print(gKARC4RandomSource.nextUniform()) //0.059348706

/*generate a next Float using gKARC4RandomSourceFromSeed*/
print(gKARC4RandomSourceFromSeed.nextUniform()) //0.059348706

/*use a shared random source*/
print(GKARC4RandomSource.sharedRandom().nextInt())//209993353

/*shuffle an array*/
let array  = [0 , 1 , 2 , 3 , 4 , 5]
var shuffledArray = gKARC4RandomSourceFromSeed.arrayByShufflingObjects(in:array)
print(shuffledArray) //[4, 2, 0, 5, 3, 1]
shuffledArray = gKARC4RandomSource.arrayByShufflingObjects(in:array)
print(shuffledArray)//[4, 2, 0, 5, 3, 1]

GKLinearCongruentialRandomSource

GKLinearCongruentialRandomSource extends the GKRandomSource source , as such it has all of its methods . The algorithm that is used by this class is faster than the GKARC4RandomSource algorithm , but it is less random , so we will have more repeating random numbers . The formula of the algorithm is

 

we multiply the current random number or the seed by a constant a , we add a constant c to the result , and we calculate the modulo by m , to get the next random number .

 

This class also defines the seed property

seed: UInt64

which changes value each time a random number is generated , and which we can use to recreate the GKLinearCongruentialRandomSource by using the class initializer that takes a seed .

init(seed: UInt64)
methods usage example
import GameplayKit


/*create an instance of GKLinearCongruentialRandomSource
 using seed generated by GKLinearCongruentialRandomSource
 */
let gKLinearCongruentialRandomSource : GKLinearCongruentialRandomSource  = GKLinearCongruentialRandomSource() ;


//get the seed that is used by gKLinearCongruentialRandomSource to generate random numbers
// the seed is an  unsigned integer
let seedGKLinearCongruentialRandomSource = gKLinearCongruentialRandomSource.seed;

// create a GKLinearCongruentialRandomSource instance from  a seed
// the seed  is the seed from the earlier gKLinearCongruentialRandomSource instance
let gKLinearCongruentialRandomSourceFromSeed : GKLinearCongruentialRandomSource  = GKLinearCongruentialRandomSource(seed: seedGKLinearCongruentialRandomSource)


// generate a next random Integer using gKLinearCongruentialRandomSource
print(gKLinearCongruentialRandomSource.nextInt()); //-186731029

// generate a next random Integer using gKLinearCongruentialRandomSourceFromSeed
// its value will be the same value generated using gKLinearCongruentialRandomSource.nextInt() method
// since we are generating deterministic random numbers
print(gKLinearCongruentialRandomSourceFromSeed.nextInt());//-186731029


/*generate an next Integer less than an upperBound using gKLinearCongruentialRandomSource*/
print(gKLinearCongruentialRandomSource.nextInt(upperBound: 8)); //0

/*generate an next Integer less than an upperBound using gKLinearCongruentialRandomSourceFromSeed*/
print(gKLinearCongruentialRandomSourceFromSeed.nextInt(upperBound: 8)); //0


/*generate a next Boolean using gKLinearCongruentialRandomSource*/
print(gKLinearCongruentialRandomSource.nextBool()) // false

/*generate a next Boolean using gKLinearCongruentialRandomSourceFromSeed*/
print(gKLinearCongruentialRandomSourceFromSeed.nextBool()) // false

/*generate a next Float using gKLinearCongruentialRandomSource*/
print(gKLinearCongruentialRandomSource.nextUniform()) //0.98541963

/*generate a next Float using gKLinearCongruentialRandomSourceFromSeed*/
print(gKLinearCongruentialRandomSourceFromSeed.nextUniform()) //0.98541963

/*use a shared random source*/
print(GKARC4RandomSource.sharedRandom().nextInt())//-1371630598

/*shuffle an array*/
let array  = [0 , 1 , 2 , 3 , 4 , 5]
var shuffledArray = gKLinearCongruentialRandomSourceFromSeed.arrayByShufflingObjects(in:array)
print(shuffledArray) //[0, 2, 3, 5, 1, 4]
shuffledArray = gKLinearCongruentialRandomSource.arrayByShufflingObjects(in:array)
print(shuffledArray)//[0, 2, 3, 5, 1, 4]

GKMersenneTwisterRandomSource

GKMersenneTwisterRandomSource extends the GKRandomSource source , as such it has all of its methods . The algorithm that is used by this class is slower than the GKARC4RandomSource algorithm , but it is more random , so we will have less repeating random numbers . The algorithm has a period length of a Mersenne prime .

This class also defines the

seed: UInt64

seed property which we can use to recreate GKMersenneTwisterRandomSource by using the initializer that takes a seed .

init(seed: UInt64)

So we will be able to recreate the random numbers generated by this given seed .

methods usage example
import GameplayKit


/*create an instance of GKMersenneTwisterRandomSource
 using seed generated by GKMersenneTwisterRandomSource
 */
let gKMersenneTwisterRandomSource : GKMersenneTwisterRandomSource  = GKMersenneTwisterRandomSource() ;


// generate a next random Integer using gKMersenneTwisterRandomSource
print(gKMersenneTwisterRandomSource.nextInt()); //1275963130


//get the seed that is used by GKMersenneTwisterRandomSource to generate random numbers
// the seed is an unsigned int
let seedGKMersenneTwisterRandomSource = gKMersenneTwisterRandomSource.seed;

// create a GKMersenneTwisterRandomSource instance from  a seed
// the seed  is the seed from the earlier gKMersenneTwisterRandomSource instance
let gKMersenneTwisterRandomSourceFromSeed : GKMersenneTwisterRandomSource  = GKMersenneTwisterRandomSource(seed: seedGKMersenneTwisterRandomSource)



// generate a next random Integer using gKMersenneTwisterRandomSourceFromSeed
// its value will be the same value generated using gKMersenneTwisterRandomSource.nextInt() method
// since we are genrating determenstic random numbers
print(gKMersenneTwisterRandomSourceFromSeed.nextInt());//1275963130


/*generate an next Integer less than an upperBound using gKMersenneTwisterRandomSource*/
print(gKMersenneTwisterRandomSource.nextInt(upperBound: 8)); //4

/*generate an next Integer less than an upperBound using gKMersenneTwisterRandomSourceFromSeed*/
print(gKMersenneTwisterRandomSourceFromSeed.nextInt(upperBound: 8)); //4


/*generate a next Boolean using gKMersenneTwisterRandomSource*/
print(gKMersenneTwisterRandomSource.nextBool()) // false

/*generate a next Boolean using gKMersenneTwisterRandomSourceFromSeed*/
print(gKMersenneTwisterRandomSourceFromSeed.nextBool()) // false

/*generate a next Float using gKMersenneTwisterRandomSource*/
print(gKMersenneTwisterRandomSource.nextUniform()) //0.4561884

/*generate a next Float using gKMersenneTwisterRandomSourceFromSeed*/
print(gKMersenneTwisterRandomSourceFromSeed.nextUniform()) //0.4561884

/*use a shared random source*/
print(GKARC4RandomSource.sharedRandom().nextInt())//54549831

/*shuffle an array*/
let array  = [0 , 1 , 2 , 3 , 4 , 5]
var shuffledArray = gKMersenneTwisterRandomSourceFromSeed.arrayByShufflingObjects(in:array)
print(shuffledArray) //[3, 5, 0, 4, 1, 2]
shuffledArray = gKMersenneTwisterRandomSource.arrayByShufflingObjects(in:array)
print(shuffledArray)//[3, 5, 0, 4, 1, 2]

Generating random numbers which follow a distribution

GKRandomDistribution

This class allow us to generate random number uniformly distributed between two values min and max. So all the random numbers that are generated have equal probability to occur or to be generated.

 

GKRandomDistribution implements the GKRandom interface , as such it implements all of its methods

nextInt()→Int 
nextInt(upperBound:Int)→Int 
nextUniform()→FLoat 
nextBool()→Bool

It also defines

init(randomSource source: GKRandom, lowestValue lowestInclusive: Int, highestValue highestInclusive: Int)

which allow us to create an instance of this class , by specifying the random source . The random source must be an instance of a class that implements GKRandom . If the random source can be recreated , we can recreate the random numbers generated by this class.

init(lowestValue lowestInclusive: Int, highestValue highestInclusive: Int)

which allow us to create an instance of this class , by specifying a min , and a max value . If we use this initializer , we cannot recreate the random numbers that are generated , since this initializer uses GKRandomSource which cannot be recreated .

init(forDieWithSideCount sideCount: Int)

which allow us to create an instance of this class , with a source of randomness of GKRandomSoure , and a lowest value of 1 , and a highest value of sideCount.

lowestValue: Int

which allow us to get the lowest random value that we can generate .

highestValue: Int

which allow us to get the highest random value that we can generate .

numberOfPossibleOutcomes: Int

which allow us to get the number of random values that we can generate . Since we are doing a uniform random distribution , this is equal to max – min + 1

init(randomSource source: GKRandom, lowestValue lowestInclusive: Int, highestValue highestInclusive: Int)
import GameplayKit


/*create an instance of GKRandomDistribution
 using an instance of GKLinearCongruentialRandomSource with a seed of 153 as a source of randomness
 */
let gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(randomSource: GKLinearCongruentialRandomSource(seed: 153), lowestValue: 0, highestValue: 10)

// generate a next random Integer using gKRandomDistribution
print(gKRandomDistribution.nextInt()); //4
print(gKRandomDistribution.nextInt()); //1


/*create an instance of GKRandomDistribution
 using an instance of GKLinearCongruentialRandomSource with a seed of 153 as a source of randomness
 */
let _gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(randomSource: GKLinearCongruentialRandomSource(seed: 153), lowestValue: 0, highestValue: 10)
print(_gKRandomDistribution.nextInt()); //4
print(_gKRandomDistribution.nextInt()); //1

if we use this method , with a random source that can be recreated , we can recreate the generated random numbers .

init(lowestValue lowestInclusive: Int, highestValue highestInclusive: Int)

if we use this initializer , we cannot recreate the random numbers that are generated .

import GameplayKit


/*create an instance of GKRandomDistribution
 using an instance of GKRandom as a source of randomness
 */
let gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(lowestValue: 0, highestValue: 5)


// generate a next random Integer using gKRandomDistribution
print(gKRandomDistribution.nextInt()); //0
print(gKRandomDistribution.nextInt()); //4



let _gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(lowestValue: 0, highestValue: 5)
print(_gKRandomDistribution.nextInt()); //5
print(_gKRandomDistribution.nextInt()); //1
init(forDieWithSideCount sideCount: Int)
/*create an instance of GKRandomDistribution
 using a default random source of GKRandomSource
 with a lowest value of 1
 and highest value of 8
 */
let gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(forDieWithSideCount: 8)
print(gKRandomDistribution.nextInt()) // 6
print(gKRandomDistribution.lowestValue) //1
print(gKRandomDistribution.highestValue) //8
print(gKRandomDistribution.numberOfPossibleOutcomes) //8

create an instance of GKRandomDistribution , with a default random source of GKRandomSource , and a low value of 1 , and a highest value of 8 , and a number of possible random numbers of 8 – 1 + 1 = 8

lowestValue: Int , highestValue: Int , numberOfPossibleOutcomes: Int

we can use these properties to get the lowest random number that we can generate , the highest one , and the number of random numbers that we can generate .

/*create an instance of GKRandomDistribution
 using an instance of GKLinearCongruentialRandomSource with a seed of 321 as a source of randomness
 */
let gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(randomSource: GKLinearCongruentialRandomSource(seed: 321), lowestValue: 0, highestValue: 10)

// get the lowest random value that can be generated
print(gKRandomDistribution.lowestValue) // 0

// get the highest random value that can be generated
print(gKRandomDistribution.highestValue) // 10

// get the number of values that can be generated
print(gKRandomDistribution.numberOfPossibleOutcomes) //11
methods implemented from GKRandom interface usage example
/*create an instance of GKRandomDistribution
 using GKMersenneTwisterRandomSource
 with a lowest value of 1
 and highest value of 6
 */
let gKRandomDistribution : GKRandomDistribution  = GKRandomDistribution(randomSource: GKMersenneTwisterRandomSource(seed: 8371), lowestValue: 1, highestValue: 6)

// generate a next random Integer using gKRandomDistribution
print(gKRandomDistribution.nextInt());//1

/*generate an next Integer less than an upperBound using gKRandomDistribution*/
print(gKRandomDistribution.nextInt(upperBound: 8)); //5

/*generate a next Boolean using gKRandomDistribution*/
print(gKRandomDistribution.nextBool()) // false

/*generate a next Float using gKRandomDistribution*/
print(gKRandomDistribution.nextUniform()) //0.33333334

GKGaussianDistribution

This class extends GKRandomDistribution , as such it has all of its method and properties . It also defines two additional properties ,

mean: Float

The mean value , to which random numbers that are generated will be closer to .

deviation: Float

this is the standard deviation , and this is by how much each value will deviate from the mean . when we have a small standard deviation this means the values are closers to the mean , when we have a large deviation , the values will be farer from the mean .

In A gaussian distribution , the values are closer to the mean.

This class has two initializer

init(randomSource source: GKRandom, lowestValue lowestInclusive: Int, 
       highestValue highestInclusive: Int)
 
init(randomSource source: GKRandom, mean: Float, deviation: Float)

the first one will take a source of randomness ,which is a class that implements the GKRandom source interface. it will also take a lowest value and highest value. they are used to generate the mean ,and the deviation . The mean is

mean = (highest + lowest) / 2

and the deviation is

deviation = (highest - lowest) / 6

, and the values that are generated are between

[mean - 3 * deviation, mean + 3 * deviation]

The second initializer ,will take the mean , and the deviation , and it will generate random numbers between

[mean - 3 * deviation, mean + 3 * deviation]
methods example
/*
 create a source of randomness
 GKARC4RandomSource
 */

let gKARC4RandomSource :GKARC4RandomSource = GKARC4RandomSource();

/*
 create an instance of GKGaussianDistribution using as a random source
 gKARC4RandomSource , and using a lowest value and highest value
 */
let gKGaussianDistribution : GKGaussianDistribution = GKGaussianDistribution(randomSource: gKARC4RandomSource, lowestValue: 0, highestValue: 20)

/*
 GKGaussianDistribution extends GKRandomDistribution implement GKRandom , so it has of the methods implemented and extended
 */

// print the next int
//the values that are generated are closer to the mean which is 20 -10 /2 = 10
print(gKGaussianDistribution.nextInt()) //9
print(gKGaussianDistribution.nextInt()) //10
print(gKGaussianDistribution.nextInt()) //12
print(gKGaussianDistribution.nextInt()) //9
print(gKGaussianDistribution.nextInt()) // 7
print()

//print the next int with upper limit of 10 , so they should be around 10 also
print(gKGaussianDistribution.nextInt(upperBound: 10))  //8
print(gKGaussianDistribution.nextInt(upperBound: 10))  //2
print(gKGaussianDistribution.nextInt(upperBound: 10))  //9
print(gKGaussianDistribution.nextInt(upperBound: 10))  //4
print(gKGaussianDistribution.nextInt(upperBound: 10))  //9
print()


//print the next float
print(gKARC4RandomSource.nextUniform()); //0.32123032
print(gKARC4RandomSource.nextUniform()); //0.57984614
print(gKARC4RandomSource.nextUniform()); //0.3413491
print(gKARC4RandomSource.nextUniform()); //0.88272184
print()


//print the next bool
print(gKARC4RandomSource.nextBool());//false
print(gKARC4RandomSource.nextBool());//false
print(gKARC4RandomSource.nextBool());//false
print(gKARC4RandomSource.nextBool());//true

GKShuffledDistribution

The class GKShuffledDistribution extends GKRandomDistribution as such it inherits all of it methods . This class is used to generate uniformly distributed random numbers , while preventing clustering of occuring . The generated random number are stored in memory in order to prevent clustering , so this can lead to high memory usage .

methods example
import GameplayKit
 
 
/*
 create a source of randomness
 GKLinearCongruentialRandomSource
 */
 
let gKLinearCongruentialRandomSource :GKLinearCongruentialRandomSource = GKLinearCongruentialRandomSource();
 
/*
 create an instance of GKShuffledDistribution using as a random source
 gKLinearCongruentialRandomSource , and using a lowest value and highest value
 */
let gKShuffledDistribution : GKShuffledDistribution = GKShuffledDistribution(randomSource: gKLinearCongruentialRandomSource, lowestValue: 0, highestValue: 20)
 
 
/*
 GKGaussianDistribution extends GKRandomDistribution implement GKRandom , so it has of the methods implemented and extended
 */
 
// print the next int
//the values that are generated are closer to the mean which is 20 -10 /2 = 10
print(gKShuffledDistribution.nextInt()) //0
print(gKShuffledDistribution.nextInt()) //12
print(gKShuffledDistribution.nextInt()) //6
print(gKShuffledDistribution.nextInt()) //2
print(gKShuffledDistribution.nextInt()) // 19
print()
 
//print the next int with upper limit of 10 , so they should be around 10 also
print(gKShuffledDistribution.nextInt(upperBound: 10))  //9
print(gKShuffledDistribution.nextInt(upperBound: 10))  //4
print(gKShuffledDistribution.nextInt(upperBound: 10))  //4
print(gKShuffledDistribution.nextInt(upperBound: 10))  //6
print(gKShuffledDistribution.nextInt(upperBound: 10))  //4
print()
 
 
//print the next float
print(gKShuffledDistribution.nextUniform()); //0.65
print(gKShuffledDistribution.nextUniform()); //0.15
print(gKShuffledDistribution.nextUniform()); //0.8
print(gKShuffledDistribution.nextUniform()); //1.0
print()
 
 
//print the next bool
print(gKShuffledDistribution.nextBool());//false
print(gKShuffledDistribution.nextBool());//false
print(gKShuffledDistribution.nextBool());//false
print(gKShuffledDistribution.nextBool());//false