# 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()

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```