Introductory Activity:

A lot to do today, so get started by reviewing notes from Part 1 on what makes a good Moose class. Create a moose class and add the properties and their initial values to the class. Outline in comments the methods: canEat and liveForYear in code and discuss what should be in each method.

The function canEat() can be as complicated as you’d like. We wanted to model that a moose may not find itself in the part of the island that has good vegetation for some reason, so we settled on a randomNumber test to see if the moose found itself in the well-vegetated portion of the island, or not. This seems to work well.

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

Summary Activity: