0

I'm just messing around slowly learning Swift, and I decided to make a really simple fighting game. All the below code worked perfectly fine when it was a class, then I decided to change it to a struct, and now on the lines in the function that would reduce the target's hp, it's giving me the following error:

Cannot use mutating member on immutable value

Here is the struct in it's entirety:

struct Player {
    let name : String
    let maxHealth : Int
    var currentHealth : Int
    let maxMana: Int
    var currentMana: Int

    init(playerName: String) {
        name = playerName
        maxHealth = 100
        currentHealth = 100
        maxMana = 100
        currentMana = 100
    }

    mutating func swingAt(target: Player) {
        if isDead(target: self) {
            print("You are dead!")
            return
        }
        let damage = Int.random(in: 0..<10)
        target.takeDamage(amount: damage) // Error:Cannot use mutating member on immutable value: 'target' is a 'let' constant
        if damage > 0 {
            print("\(self.name) does \(damage) damage to \(target.name)!")
        }
        else {
            print("\(self.name) misses \(target.name)!")
        }
        if isDead(target: target) {
            print("\(self.name) has slain \(target.name)!")
        }
    }

    mutating func swingFiveTimesAt(target: Player) {
        if isDead(target: self) {
            print("You are dead!")
            return
        }
        for _ in 1...5 {
            let damage = Int.random(in: 0..<10)
            target.takeDamage(amount: damage) // Error:Cannot use mutating member on immutable value: 'target' is a 'let' constant
            if damage > 0 {
                print("\(self.name) does \(damage) damage to \(target.name)!")
            }
            else {
                print("\(self.name) misses \(target.name)!")
            }
        }
        if isDead(target: target) {
            print("\(self.name) has slain \(target.name)!")
        }
    }

    mutating func castFireball(target: Player) {
        if isDead(target: self) {
            print("You are dead!")
            return
        }
        if self.currentMana < 50 {
            print("\(self.name) only has \(self.currentMana), but needs 50 mana to cast this spell!")
            return
        }
        let damage = Int.random(in: 1..<50)
        target.takeDamage(amount: damage) // Error:Cannot use mutating member on immutable value: 'target' is a 'let' constant
        self.currentMana -= 50
        print("\(self.name) throws a huge fireball at \(target.name), doing \(damage) damage!")
        if isDead(target: target) {
            print("\(self.name) has slain \(target.name)!")
        }
    }

    func isDead(target: Player) -> Bool {
        if target.currentHealth <= 0 {
            return true
        } else {
            return false
        }
    }

    mutating func takeDamage(amount: Int) {
        self.currentHealth -= amount
    }
}

Any ideas how I can achieve the desired functionality?

1 Answer 1

2

I searched for about 45 minutes before posting this, and of course immediately after posting this I was able to find an answer. Turns out adding 'inout' fixed it!

Broken: mutating func swingAt(target: Player) {

Working: mutating func swingAt(target: inout Player) {

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.