Introductory Activity:

Review the code you wrote last time and decide what you need to finish today.

The following is a good goal for the end of today. Results from the simulation are found below the code.

Moose Class:

`class Moose {    var mooseAgeMaturity = 5 // age a moose needs to be to reproduce    var mooseLongevityAge = 100 // number of years a moose will live naturally    var age = 0    var alive = true // moose is alive or dead    var vegetationNeededToSurvive = 0.01 // each moose needs to eat 1% worth of the islands vegetation per year    var mooseBirthRate = 0.75 // each moose will create 0.75 moose each year once it’s old enough to mate    var starvation = 0    var environment: Environment    init(in environment: Environment, age: Int) {        mooseAgeMaturity = 5        let deltaLife = Int.random(in: -6 ... 6)  // randomize the longevity of a moose - simulation not very sensitive to this feature        mooseLongevityAge = 20 + deltaLife        self.age = age        alive = true        vegetationNeededToSurvive = 0.002  //  fraction of the region's vegetation a single moose eats per year        mooseBirthRate = 0.75  // fraction of a moose another moose gives birth to, assuming it is mature enough        starvation = 0    //  counter to keep track of how many years a moose has gone without sufficient food        self.environment = environment    }    func canEat() -> Bool {        //  current vegetation cover in the region is a fraction from 0.0 to 1.0        //  randomize the probability that a moose finds itself in the vegetated fraction of the region and can eat sufficiently for a year        let randomNumber = Double.random(in: 0.0 ... 1.0)        if randomNumber > environment.vegCover {            return false        }        return true    }        func liveForYear() {                // If a moose doesn’t find food for two years in a row, it dies        // If a moose survives until mooseLongevityAge, it dies                if canEat() {            age += 1            environment.vegCover -= vegetationNeededToSurvive        } else {            starvation += 1        }        if starvation >= 2 { alive = false }        if age >= mooseLongevityAge { alive = false }            }   }`

Environment Class:

`class Environment {    var vegCover = 1.0    let vegatationRegrowthRate = 0.1  // rate at which vegetation regrows each year    var mooseArray = [Moose]()  //  create an empty array of moose        func updateVegetation() {        //  grow vegetation cover for a year        vegCover += vegatationRegrowthRate        if vegCover > 1.0 { vegCover = 1.0 }    }        //  update simulation population    func updateMoosePopulation() {                var newMooseArray = [Moose]()        var newMooseBabies = 0.0        //  check and see if there are any dead moose, of so, remove them from the mooseArray        for i in mooseArray.indices {            let thisMoose = mooseArray[i]            //  each moose experiences a year            thisMoose.liveForYear()                       //  determine how many new moose will be born this year            if thisMoose.alive {                newMooseArray.append(thisMoose)                if thisMoose.age >= thisMoose.mooseAgeMaturity {                    newMooseBabies += thisMoose.mooseBirthRate                }            }        }                //  have moose reproduce        let numberOfBabies = Int(newMooseBabies)        //  add new moose babies to the herd        for _ in 0 ..< numberOfBabies {            newMooseArray.append(Moose(in: self, age: 0))        }                mooseArray = newMooseArray    }}`

Simulation Class:

`class Simulation {    let numberOfInitialMoose = 80    let simulationLength = 1000 //  number of years for the simulation    var year = 0 // year of the simulation    var environment = Environment()    var numberOfMooseInSimulation: Int { // a computed property that return the current number of moose in herd        return environment.mooseArray.count    }    init() {  // initialize the simulation        environment = Environment()        for _ in 0 ..< numberOfInitialMoose {            let initialAge = Int.random(in: 1 ... 30)            environment.mooseArray.append(Moose(in: environment, age: initialAge))        }    }    //  Simulation of Isle Royale Moose    func simulateYear() {        environment.updateVegetation()        environment.updateMoosePopulation()    }        func runSimulation() {        for year in 0 ..< simulationLength {            simulateYear()            print("\(year), \(numberOfMooseInSimulation), \(environment.vegCover * 100.0)")        }    }    }`

Main Program:

The main program is short and sweet. Create a single instance of the Simulation class and call the runSimulation method on the instance.

`var sim001 = Simulation()sim001.runSimulation()`

Simulation Results:

Summary Activity:

Discuss the results of the 1000-year simulation:

Questions:

• How realistic is the model?
• Does the model match the observations in any ways (not enough moose; ~25 cycle of moose population expansion and decay)
• Ideas on how we can make the simulation match observations more accurately (decrease amount moose eats per year? increase moose birth rates? increase vegetation growth rates

Homework?

What kinds of systematic experiments would you like to run with our model?

Spend the last 5 minutes dividing up simulation experiments for each student to perform. Use the questions above to guide the experiments. Have the students write clear hypotheses before leaving class and performing the experiments.