extension EncounterSeries{

  static func GenerateEncounterSeries(forPlaneViewController planeViewController: PlaneViewController,withMaxLetter maxLetters: Int, withNumberOfEncounters numberOfEncounters: Int, withMaxFireballs maxFireballs: Int, withMaxSpikeBalls maxSpikeBalls: Int, withMaxSpaceCraft maxSpaceCraft: Int, withMaxAlienHeads maxAlienHeads: Int, withMaxWaitTime maxWaitTime: Int) -> EncounterSeries{
        
        if(numberOfEncounters < 2){
            fatalError("Error: there must be at least two encounters minimum in order for an encounter series to be generated")
        }
        
        let getMaxWaitTime = {
            
            return Double(4.00 + Double(arc4random_uniform(UInt32(maxWaitTime))))

        }
        
        
        let getRandomNumberOfSpikeBalls: ()->Int = {
            
            let maximumNum = maxSpikeBalls <= 0 ? 0: maxSpikeBalls
            
            return Int(arc4random_uniform(UInt32(maximumNum)))
        }
        
        let getRandomNumberOfFireballs: ()->Int = {
            
            let maximumNum = maxFireballs <= 0 ? 0: maxFireballs
            
            return  Int(arc4random_uniform(UInt32(maximumNum)))
        }
        
        let getRandomNumberOfSpaceCraft: ()->Int = {
            
            let maximumNum = maxSpaceCraft <= 0 ? 0: maxSpaceCraft
            
            return Int(arc4random_uniform(UInt32(maximumNum)))
        }
        
        let getRandomNumberOfAlienHeads: ()->Int = {
            let maximumNum = maxAlienHeads <= 0 ? 0: maxAlienHeads
            
            return Int(arc4random_uniform(UInt32(maximumNum)))
        }
        
        let getRandomNumberOfLetters: ()->Int = {
            let maximumNum = maxLetters <= 0 ? 0: maxLetters
            
            return Int(arc4random_uniform(UInt32(maximumNum)))
            
        }
       
        
        let (firstWaitTime,fireballNum1,spikeBallNum1,spaceCraftNum1,letterNum1,alienHeadsNum1) = (getMaxWaitTime(),getRandomNumberOfFireballs(),getRandomNumberOfSpikeBalls(),getRandomNumberOfSpaceCraft(),getRandomNumberOfLetters(),getRandomNumberOfAlienHeads())
       
     
        
        let firstEncounter = Encounter(waitTime: firstWaitTime, numberOfSpikeBalls: spikeBallNum1, numberOfSpaceCraft: spaceCraftNum1, numberOfLetters: letterNum1, numberOfAlienHeads: alienHeadsNum1, numberOfFireballs: fireballNum1)
        
        let (secondWaitTime,fireballNum2,spikeBallNum2,spaceCraftNum2,letterNum2,alienHeadsNum2) = (getMaxWaitTime(),getRandomNumberOfFireballs(),getRandomNumberOfSpikeBalls(),getRandomNumberOfSpaceCraft(),getRandomNumberOfLetters(),getRandomNumberOfAlienHeads())
        
        
        
        var nextEncounter = firstEncounter.setNextEncounter(waitTime: secondWaitTime, numberOfSpikeBalls: spikeBallNum2, numberOfSpaceCraft: spaceCraftNum2, numberOfLetters: letterNum2, numberOfFireballs: fireballNum2, numberOfAlienHeads: alienHeadsNum2)
        
        for _ in 1..< numberOfEncounters-2{
            
            let (nextWaitTime,nextFireballNum,nextSpikeBallNum,nextSpaceCraftNum,nextNumberOfLetters,nextNumberOfAlienHeads) = (getMaxWaitTime(),getRandomNumberOfFireballs(),getRandomNumberOfSpikeBalls(),getRandomNumberOfSpaceCraft(),getRandomNumberOfLetters(),getRandomNumberOfAlienHeads())
            
            nextEncounter = nextEncounter.setNextEncounter(waitTime: nextWaitTime, numberOfSpikeBalls: nextSpikeBallNum, numberOfSpaceCraft: nextSpaceCraftNum, numberOfLetters: nextNumberOfLetters, numberOfFireballs: nextFireballNum, numberOfAlienHeads: nextNumberOfAlienHeads)
            
        }
        
        return EncounterSeries(planeViewController: planeViewController, firstEncounter: firstEncounter)
    }
    
    static func generateRandomNumberFunction(withDefaultValue defaultNum: Int, andWithMaxNumber max: Int) -> ()->Int{
        
        return {
            let maximumNum = max <= defaultNum ? defaultNum: max
        
            return Int(arc4random_uniform(UInt32(maximumNum)))
        }
    }
    
    static func showNumberOf(spikeballs: Int, spaceCraft: Int, alienHeads: Int, fireballs: Int, letters: Int, andWaitTime waitTime: Double){
        
        print("The generated wait time is: \(waitTime), generated spikeballs are: \(spikeballs), generated space craft are: \(spaceCraft), generated alien heads are: \(alienHeads), generated fireballs: \(fireballs), letters: \(letters)")
    }

}
  

     
   
extension EncounterSeries{
    
    
    static func GenerateEncounterSeries(forPlaneViewController planeViewController: PlaneViewController, forLevelTrack levelTrack: GameHelper.LevelTrack, andforLevel level: Int) -> EncounterSeries{
        
        switch level {
            
            /** Get encounter series for fireball track  **/
        case 0...3 where levelTrack == .FireBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 200, withMaxFireballs: level+10, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)
        case 4...7 where levelTrack == .FireBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 50, withMaxFireballs: level+5, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0, withMaxAlienHeads: 0, withMaxWaitTime: 4)
        case 8...11 where levelTrack == .FireBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 3, withNumberOfEncounters: 25, withMaxFireballs: level, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 4)
        case 12...15 where levelTrack == .FireBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 2, withNumberOfEncounters: 25, withMaxFireballs: level-2, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 3)
        case 16...30 where levelTrack == .FireBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 2, withNumberOfEncounters: 25, withMaxFireballs: level-5, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 3)
        case 31...10000 where levelTrack == .FireBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 2, withNumberOfEncounters: 20, withMaxFireballs: level-5, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 3)

            
            /** Get encounter series for spaceship track  **/

        case 0...3 where levelTrack == .SpaceShips:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 5, withNumberOfEncounters: 150, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: level+9,withMaxAlienHeads: 0, withMaxWaitTime: 3)
        case 4...7 where levelTrack == .SpaceShips:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 50, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: level+10,withMaxAlienHeads: 0, withMaxWaitTime: 4)
        case 8...11 where levelTrack == .SpaceShips:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: level+5,withMaxAlienHeads: 0, withMaxWaitTime: 3)
        case 12...15 where levelTrack == .SpaceShips:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 2, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: level,withMaxAlienHeads: 0, withMaxWaitTime: 2)
        case 16...30 where levelTrack == .SpaceShips:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 2, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: level,withMaxAlienHeads: 0, withMaxWaitTime: 2)
        case 31...10000 where levelTrack == .SpaceShips:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 2, withNumberOfEncounters: 20, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: level,withMaxAlienHeads: 0, withMaxWaitTime: 2)

            
            /** Get encounter series for spikeball track  **/

        case 0...3 where levelTrack == .SpikeBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 100, withMaxFireballs: 0, withMaxSpikeBalls: level+9, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)
        case 4...7 where levelTrack == .SpikeBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 50, withMaxFireballs: 0, withMaxSpikeBalls: level+5, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)
        case 8...11 where levelTrack == .SpikeBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: level, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)
        case 12...15 where levelTrack == .SpikeBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: level, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)
        case 16...30 where levelTrack == .SpikeBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: level, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)
        case 31...10000 where levelTrack == .SpikeBalls:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 20, withMaxFireballs: 0, withMaxSpikeBalls: level, withMaxSpaceCraft: 0,withMaxAlienHeads: 0, withMaxWaitTime: 5)

        
            /** Get encounter series for turret track  **/

        case 0...3 where levelTrack == .AlienHeads:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 100, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: level+6, withMaxWaitTime: 5)
        case 4...7 where levelTrack == .AlienHeads:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 6, withNumberOfEncounters: 50, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: level+5, withMaxWaitTime: 5)
        case 8...11 where levelTrack == .AlienHeads:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: level, withMaxWaitTime: 5)
        case 12...15 where levelTrack == .AlienHeads:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: level, withMaxWaitTime: 5)
        case 16...30 where levelTrack == .AlienHeads:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: level, withMaxWaitTime: 5)
        case 31...10000 where levelTrack == .AlienHeads:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 4, withNumberOfEncounters: 25, withMaxFireballs: 0, withMaxSpikeBalls: 0, withMaxSpaceCraft: 0,withMaxAlienHeads: level, withMaxWaitTime: 5)
        default:
            return EncounterSeries.GenerateEncounterSeries(forPlaneViewController: planeViewController, withMaxLetter: 3, withNumberOfEncounters: 25, withMaxFireballs: 2, withMaxSpikeBalls: 2, withMaxSpaceCraft: 2,withMaxAlienHeads: level, withMaxWaitTime: 5)

        }
        
    }
    
  
}



  

Now, we define an executeEncounter() function, which will will be the key function of this class. After performing a check for game state (i.e. if the game is in a paused state or the hasTerminatedEncounterSeries boolean flag is set to true), the no further encounters are executed. The hasTerminatedEncounterSeries boolean flag was added here as workaround to a bug that occurred during development and provided an additional means of stopping the execution of the encounter series, since it is accessible from the main game view controller, but the implementation details of this are not provided here in order to keep focused on the main point of the tutorial.

  
     
    

Now that we have our linked list defined, we are ready to go one step further, and create a generator class that can use customizable parameters for creating EncounterSeries that we can customize for different game levels based on the difficulty level or the specific enemies that should appear for that level. Stay tuned!

To continue, please click here

If you feel confused or are having trouble following, you can go back to the previous page or back to the iOS tutorials table of contents table of contents.