Chapter 10, Challenge 3, question on Structs

Hi,
I have been working on Chapter 10, challenge 3 and am stuck. While I’ve looked at the solution, my approach is slightly different and I’m trying to understand what is happening.

// Battleship = write the game engine for a baattleship like game.
struct Coordinate {
    let x: Int
    let y: Int
}

struct ship {
    let origin: Coordinate
    let orientation: String
    let length: Int
    var hits: Int = 0
    
    mutating func isHit(coordinate: Coordinate) -> Bool {
        if orientation == "Right" {
            if origin.y == coordinate.y &&
                coordinate.x >= origin.x &&
                coordinate.x - origin.x < length {
                self.hits += 1
                return true
            }
        } else {
            if origin.x == coordinate.x &&
                coordinate.y >= origin.y &&
                coordinate.y - origin.y < length {
                self.hits += 1
                return true
            }
        }
        return false
    }
    
    func isSunk() -> Bool {
        if self.hits >= length {
            return true
        } else {
            return false
        }
    }
}

struct Board {
    var ships: [ship] = []
    func fire(location: Coordinate) -> Bool {
        for ship in ships {
            if ship.isHit(coordinate: location) { // <-x Cannot use mutating member on immutable value
                print("Hit")
                return true
            }
        }
        return false
    }
}

So this code is very similar to the solution given with the book, but I’ve added to the ship struct a variable Hits and a isSunk method to determine if the ship was sunk. In this isHit method I increment hits if its a hit, and isSunk returns true if if hits >= length. I had to make the isHit method mutable because it modified the hits variable.

Seemed simple enough, but when I wrote the board struct and try to use the ship method isHit, I get and error "Cannot use mutating member on immutable value: ‘ship’ is a ‘let’ constant.

Spent a couple of hours going through stack-overflow and other sites, but I can’t seem to find anything related to this issue.

Any help appreciated.
thanks,
Jim Kardach

@jimkardach ship is declared as a constant inside the for loop by default, so you can’t call the isHit(coordinate:) mutable method on it in this case.

In order to fix this, simply define ship as a variable in the for loop and you are good to go:

for var ship in ships {
  // original code
}

Please let me know if you have any other questions or issues about the whole thing when you get a chance. Thank you!

Thank-you. It did not occur to me that the for loop was default let and you could add a var to it.

Thanks!
Jim Kardach

1 Like

This topic was automatically closed after 166 days. New replies are no longer allowed.