I feel like I got a little sloppy with these challenges. Any alternative suggestions are welcome.
Bronze Challenge:
I modeled my code based on the principle that Zombies (or any monsters, for that matter) could potentially get stronger–for example, after it is instantiated somewhere else in the code and it’s power is directly manipulated (if we choose to keep that public), we would still be able to reduce the population of the current town to 0 if the population threshold is exceeded and not go into negative numbers.
super.terrorizeTown() only needs to be called if there is a population left after the Zombie is done terrorizing, so I included that in only the default case in the switch statement.
And lastly, I changed my new zombieTerrorPower and population to be a UInt, because it made more sense to me that the power of a monster would be a positive number, not a negative number (same with the population). Plus, it allows me some compile-time safety so that I know what I’m getting (no negative numbers!). This means a bit of refactoring, adding a check to see if a monster is attacking, but worth the effort.
/// Town.swift
struct Town {
    var population: UInt   = 5422
    var numberOfStoplights = 4
    var isMonsterAttacking = false
    func printDescription() {
        print("Population: \(population), number of stoplights: \(numberOfStoplights)")
    }
    mutating func changePopulation(by amount: UInt) {
        if isMonsterAttacking {
            population -= amount
        } else {
            population += amount
        }
    }
}
/// Zombie.swift
class Zombie: Monster {
    var walksWithLimp           = true
    var zombieTerrorPower: UInt = 10
    final override func terrorizeTown() {
        town?.isMonsterAttacking = true
        if let currentPop = town?.population {
            switch currentPop {
                case 0: // no population--do nothing.
                    print("\(self.name) tried terrorizing but everyone's dead...nobody left to terrorize.")
                case 1 ... zombieTerrorPower: // scales with zombie power
                    town?.population = 0
                    print("\(self.name) terrorized the town, and now everyone is dead.")
                default: // fallback
                    super.terrorizeTown()
                    town?.changePopulation(by: zombieTerrorPower)
            }
        }
        town?.isMonsterAttacking = false
    }
}
Silver Challenge:
Similar in structure to the Zombie, but less cases (more work to do in each case though):
/// Vampire.swift
class Vampire: Monster {
    var convertedVamps           = [Vampire]()
    var vampireTerrorPower: UInt = 1
    final override func terrorizeTown() {
        town?.isMonsterAttacking = true
        if let currentPop = town?.population {
            switch currentPop {
                case 0: // no population--do nothing.
                    print("\(self.name) tried terrorizing but everyone's either dead or a vampire...nobody left to terrorize.")
                    printVampireCount()
                default: // fallback
                    super.terrorizeTown()
                    town?.changePopulation(by: vampireTerrorPower)
                    convertedVamps.append(Vampire())
                    printVampireCount()
            }
        }
        town?.isMonsterAttacking = false
    }
    func printVampireCount() {
        print("There are \(convertedVamps.count) vampires in this town.")
    }
}
/// main.swift (testing the code)
var myTown = Town()
myTown.printDescription()
let dracula = Vampire()
dracula.name = "Dracula"
dracula.town = myTown
dracula.terrorizeTown()
dracula.terrorizeTown()
dracula.terrorizeTown()
dracula.town?.printDescription()
let fredTheZombie = Zombie()
fredTheZombie.town = myTown
fredTheZombie.name = "Zombie"
fredTheZombie.zombieTerrorPower = 10000
fredTheZombie.terrorizeTown()
fredTheZombie.town?.printDescription()
Console Output:
Population: 5422, number of stoplights: 4
Dracula is terrorizing a town!
There are 1 vampires in this town.
Dracula is terrorizing a town!
There are 2 vampires in this town.
Dracula is terrorizing a town!
There are 3 vampires in this town.
Population: 5419, number of stoplights: 4
Zombie terrorized the town, and now everyone is dead.
Population: 0, number of stoplights: 4

