Below is the complete project. It does not run because I wanted to verify the mayor’s anxiety level is private. Comment out the mayorsAnxiety
declaration and final print()
statement in main.swift
, or remove the private access level from the mayor’s stored instance property to get the code to run.
//
// main.swift
// MonsterTown
//
import Foundation
var myTown = Town()
let myTownSize = myTown.townSize
print(myTownSize)
myTown.changePopulation(by: 1_000_000)
print("Size: \(myTown.townSize); population: \(myTown.population)")
let fredTheZombie = Zombie()
fredTheZombie.town = myTown
fredTheZombie.terrorizeTown()
fredTheZombie.town?.printDescription()
print("Victim pool: \(fredTheZombie.victimPool)")
fredTheZombie.victimPool = 500
print("Victim pool: \(fredTheZombie.victimPool)")
print(Zombie.spookyNoise)
if Zombie.isTerrifying {
print("Run away!")
}
// When there is no town, there is no mayor. Use a default value of -1.
// This code does not compile because of access restrictions on the
// mayor's anxiety.
let mayorsAnxiety = fredTheZombie.town?.mayor.anxietyLevel ?? -1
print("The mayor's anxiety level is \(mayorsAnxiety).")
//
// Town.swift
// MonsterTown
//
import Foundation
struct Town {
static let world = "Earth"
let region = "Middle"
var mayor = Mayor()
var population = 5_422 {
didSet(oldPopulation) {
if population <= oldPopulation {
print("The population has changed to \(population) "
+ "from \(oldPopulation).")
mayor.sendThoughtsAndPrayers()
}
}
}
var numberOfStoplights = 4
enum Size {
case small
case medium
case large
}
var townSize: Size {
switch population {
case 0...10_000:
return Size.small
case 10_001...100_000:
return Size.medium
default:
return Size.large
}
}
func printDescription() {
print("Populations: \(population); number of stoplights: "
+ "\(numberOfStoplights)")
}
mutating func changePopulation(by amount: Int) {
population += amount
}
}
//
// Mayor.swift
// MonsterTown
//
import Foundation
struct Mayor {
private var anxietyLevel = 0
mutating func sendThoughtsAndPrayers() {
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.")
anxietyLevel += 1
}
}
//
// Monster.swift
// MonsterTown
//
import Foundation
class Monster {
static let isTerrifying = true
class var spookyNoise: String {
return "Grrr"
}
var town: Town?
var name = "Monster"
var victimPool: Int {
get {
return town?.population ?? 0
}
set(newVictimPool) {
town?.population = newVictimPool
}
}
func terrorizeTown() {
if town != nil {
print("\(name) is terrorizing a town!")
} else {
print("\(name) hasn't found a town to terrorize yet...")
}
}
}
//
// Vampire.swift
// MonsterTown
//
import Foundation
class Vampire: Monster {
var thralls = [Vampire]()
override func terrorizeTown() {
let population = town?.population ?? 0
// Try to capture one of the townspeople.
if population > 0 {
town?.changePopulation(by: -1)
thralls.append(Vampire())
}
super.terrorizeTown()
}
}
//
// Zombie.swift
// MonsterTown
//
import Foundation
class Zombie: Monster {
class override var spookyNoise: String {
return "Brains..."
}
var walksWithLimp = true
private(set) var isFallingApart = false
func regenerate() {
walksWithLimp = false
}
override func terrorizeTown() {
if !isFallingApart {
town?.changePopulation(by: -10)
}
super.terrorizeTown()
regenerate()
}
}