Search code examples
swiftprotocolsinit

Protocol and init argument


An ex-collegue left a game uncomplete and undocumented.

When reading his code I found:

protocol EnemyMovement {
    func forward(speedPercent: Int)
    func reverse(speedPercent: Int)
    func left(speedPercent: Int)
    func right(speedPercent: Int)
}

protocol Enemy {
    var name: String {get set}
    var enemyMovement: EnemyMovement {get set}

    init (name: String, enemyMovement: EnemyMovement)
}

class EnemyInstance: Enemy {
    var name = "No enemy Name"
    var enemyMovement: EnemyMovement

    required init (name: String, enemyMovement: EnemyMovement) {
        self.name = name
        self.enemyMovement = enemyMovement
//...
}

I could not found a concrete instance of EnemyInstance, but if it's quite clear how to pass the name string, I don't understand how is EnemyMovement supposed to be passed.

var enemy = EnemyInstance(name: "zombie", enemyMovement?...)

Any idea?


Solution

  • Since parameter has to be of type conforming to EnemyMovement, including these methods, you have to pass this object. So, you can try to create example struct

    struct Movements: EnemyMovement {
    
        func forward(speedPercent: Int) {
            print(speedPercent)
        }
    
        func reverse(speedPercent: Int) {
            print(speedPercent)
        }
    
        func left(speedPercent: Int) {
            print(speedPercent)
        }
    
        func right(speedPercent: Int) {
            print(speedPercent)
        }
    
    }
    

    now as parameter for EnemyInstance initializer pass new instance of Movements

    var enemy = EnemyInstance(name: "zombie", enemyMovement: Movements())
    

    then you can call some method on enemyMovement property of your class and code inside this certain method gets executed (in this case it should print speedPercent)

    required init (name: String, enemyMovement: EnemyMovement) {
        self.name = name
        self.enemyMovement = enemyMovement
        enemyMovement.forward(speedPercent: 2) // prints 2
    }