Gold challenge help

#1

Anybody has any idea how to do the Gold Challenge for this chapter. I was thinking that since a zombie attack signals decrease in the town’s population then within the didSet of the population change we can update anxiety of the mayor. I realize though that a Vampire can also attack, so how can I check that the attack was indeed made from a Zombie, and how might I set up observer properties to check this behavior and update the anxiety level accordingly?

#2

I based my solution on the fact that a zombie decreases the population by 10, rather than 1 like the vampire. So, I have my town code pass the amount of population change to the mayor struct.

``````    var mayor = Mayor()
var population = 5422 {
didSet(oldPopulation) {
if population < oldPopulation {
print("The population has changed to \(population) from \(oldPopulation)")
mayor.tragedyStatement(oldPopulation - population)
}
}
}``````

Then, the mayor evaluates if the decrease is related to a zombie attack (i.e., equal to 10) and increases the anxietyLevel.

``````struct Mayor {
private var anxietyLevel = 0

mutating func tragedyStatement(decrease: Int) {
print("I'm deeply saddened to hear about this latest tragedy. I promise that my office is looking into the nature of this rash of violence")
if decrease == 10 {
self.anxietyLevel += 1
}
}
}``````

#3
``````struct Mayor {
private var anxietyLevel = 0

mutating func noticeAttack() {
print("I'm deeply saddened to hear about this latest tragedy. I promise that my office is looking into the nature of this rash violence.")
anxietyLevel++
}
}

struct Town {
static let region = "South"
var population = 5422 {
didSet(oldPopulation) {
if population < oldPopulation {
print("The population has changed to \(population) from \(oldPopulation).")
mayor.noticeAttack()
}
}
}

enum Size {
case Small
case Medium
case Large
}

var townSize: Size {
get {
switch self.population {
case 0...10000:
return Size.Small
case 10001...1000000:
return Size.Medium
default:
return Size.Large
}
}
}

var mayor = Mayor()
var numberOfStoplights = 4

func printTownDescription() {
print("Population: \(population); number of stoplights: \(numberOfStoplights)")
}

mutating func changePopulation(amount: Int) {
population += amount
}
}``````

#4

There are tons of valid approaches. I chose to add a private boolean property to Mayor, a mutating function to set it, and a conditional check within Mayor.statement() to increase anxiety and reset the flag.

[code]struct Mayor {
private var anxietyLevel = 0
private var isZombieAttack = false

``````mutating func statement() {
print("I'm deeply saddened to hear about this latest tragedy. I promise that my office is looking into the nature of this rash of violence.")
if isZombieAttack {
anxietyLevel++
isZombieAttack = false
}
}

mutating func setZombieAttack() {
isZombieAttack = true
}
``````

}
[/code]
The boolean is then set when a Zombie instance invokes terrorizeTown().

``` final override func terrorizeTown() { if !isFallingApart { if town?.population > 0 { town?.changePopulation(-10) } town?.mayor.setZombieAttack() } super.terrorizeTown() } ```
If we were to extend special Mayor behavior to additional Monsters, I’d start by simply changing the boolean to an enum and adding a Monster type parameter to the attack setting function.

#5

Hi.
I used a fairly simple solution, including a function in the mayor struct that increases the anxiety level and then calling this function each time the zombies attack.
I used different functions for the anxiety level and the mayor statement, because the statement should be theoretically issued each time the population decreases (due to a zombie, vampire or generic monster attack), while the anxiety should be increased only in case of a zombie attack.

It works, but looking at the more complex solutions proposed by others, I’m starting to think that I didn’t completely fulfill the purpose of the challenge…

Mayor.swift:

``````struct Mayor {
private var anxietyLevel: Int = 0

mutating func increaseAnxiety() {
self.anxietyLevel += 10
}

func statement() {
print ("I'm deeply saddened to hear about this latest tragedy. I promise that my office is looking into the nature of this rash of violence.")
}
}
``````

Zombie.swift:

``````final override func terrorizeTown() {
if town?.population == 0 {
print("There's no one left to terrorize!")
return
}
if town?.population < 10 {
print("The monster terrorized the last people in town")
town?.population = 0
town?.mayor?.increaseAnxiety()
return
}
if town?.population > 10 {
town?.changePopulation(-10)
town?.mayor?.increaseAnxiety()
super.terrorizeTown()
}

}``````

#6

For what it’s worth, I feel like yours is the simpler, more robust solution. In the first solution, there could be other monsters that also decrement the population by 10, which would cause an unwanted result.