Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Nate Bird
7,999 PointsHow is the Destructable protocol useful in this example?
I expanded on the protocol example of the tower defense game and have the following code:
struct Point {
var x: Int
var y: Int
func pointsAroundMe(withRange range: Int) -> [Point] {
var results: [Point] = []
for x in (self.x - range)...(self.x + range) {
for y in (self.y - 1)...(self.y + 1) {
let point = Point(x: x, y: y)
results.append(point)
}
}
return results
}
}
enum Direction {
case Up, Down, Left, Right
}
protocol Movable {
func move(direction: Direction, distance: Int)
}
protocol Destructable {
func decreaseLife(factor: Int)
}
protocol Attackable {
var strength: Int { get }
var range: Int { get }
func attack(player: PlayerType)
}
protocol PlayerType {
var position: Point { get set }
var life: Int { get set }
init(point: Point)
}
class Enemy: PlayerType, Destructable, Attackable, Movable {
var position: Point
var life: Int = 10
var strength: Int = 5
var range: Int = 2
required init(point: Point) {
self.position = point
}
func decreaseLife(factor: Int) {
self.life -= factor
}
func attack(var player: PlayerType) {
player.life = player.life - strength
}
func move(direction: Direction, distance: Int) {
switch direction {
case .Up: position.y += 1
case .Down: position.y -= 1
case .Left: position.x -= 1
case .Right: position.x += 1
}
}
}
class Tower: PlayerType, Destructable, Attackable {
var position: Point
var life: Int = 10
var strength: Int = 1
var range: Int = 1
required init(point: Point) {
self.position = point
}
func decreaseLife(factor: Int) {
self.life -= factor
}
func attack(var player: PlayerType) {
if inRange(self.position, range: self.range, target: player.position) {
while player.life >= 0 {
player.life = player.life - strength
}
print("Enemy vanquished!")
} else {
print("Darn! Out of range!")
}
}
func inRange(position: Point, range: Int, target: Point) -> Bool {
let availablePositions = position.pointsAroundMe(withRange: range)
for point in availablePositions {
if point.x == target.x && point.y == target.y {
return true
}
}
return false
}
}
This works fine but the Destructable method .decreaseLife is not available when using PlayerType for the player. If I change the attack method in the Tower class to use Enemy then it is available but I no longer conform to the Attackable protocol.
func attack(player: Enemy) {
if inRange(self.position, range: self.range, target: player.position) {
while player.life >= 0 {
player.decreaseLife(strength)
}
print("Enemy vanquished!")
} else {
print("Darn! Out of range!")
}
}
Any ideas on how this can be refactored to use these methods while still being able to conform to the protocols?