Working on a Apple tutorial for swift and have the code below and keep getting the
Instance member 'formattedWord' cannot be used on type 'Game' error message.
I cannot quite figure out why the message, I understand what It is telling me, but not sure how to resolve the error.
Thanks for your help.
import UIKit
class ViewController: UIViewController {
var listOfWords = ["bad", "ace","dead", "feed","bee"]
let incorrectMovesAllowed = 7
var totalWins = 0
var totalLosses = 0
var currentGame: Game! //Ok for Game! not have a value for a short period of time.
@IBOutlet weak var treeImageView: UIImageView!
@IBOutlet weak var correctWordLabel: UILabel!
@IBOutlet weak var scoreLabel: UILabel!
@IBOutlet var letterButtons: [UIButton]!
@IBAction func buttonPressed(_ sender: UIButton) {
sender.isEnabled = false
let letterString = sender.title(for: .normal)!
_ = Character(letterString.lowercased())
}
override func viewDidLoad() {
super.viewDidLoad()
newRound()
updateUI()
// Do any additional setup after loading the view, typically from a nib.
}
func newRound() {
let newWord = listOfWords.removeFirst()
currentGame = Game(word: newWord, incorrectMovesRemaining:incorrectMovesAllowed, guessedLetters: [])
updateUI()
}
@IBAction func buttonTapped(_ sender: UIButton) {
sender.isEnabled = false
let letterString = sender.title(for: .normal)!
let letter = Character(letterString.lowercased())
currentGame.playerGuessed(letter: letter)
updateUI()
}
func updateUI() {
correctWordLabel.text = Game.formattedWord
scoreLabel.text = "Wins: \(totalWins), Losses: \totalLosses)"
treeImageView.image = UIImage(named: "Tree \(currentGame.incorrectMovesRemaining)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
formattedWord is [presumably — you didn't show that part of the code] a property in the Game class. That means you need a Game object, such as currentGame, to get the property from.
You've just written the name of the class (Game.formattedWord) instead of an object of the class. The compiler is saying you can't do that.
Some Swift terminology will help you with the error message. An object of some class is an instance of the class. For example, property currentGame is set to an instance of Game.
Properties that can have a different value for each different instance are called instance properties. (There are also class properties, which have a single value for the class as a whole, unrelated to any specific instance.)
A member of a class is a property or function in the class. An instance member, therefore, is an instance property or an instance function (aka instance method).
If you put all those pieces together, your error message says, in effect: "Only instances of class Game can provide a value for formattedWord."
Thank you and sorry for the delayed response. Here is the other part of the code below, I totally understand what you are saying but what I did looks correct based on what you said. Am I missing something?
import Foundation
struct Game {
var word: String
var incorrectMovesRemaining: Int
var guessedLetters: [Character]
var formattedWord: String {
var guessedWord = ""
for letter in word.characters {
if guessedLetters.contains(letter) {
guessedWord += "(letter)"
} else {
guessedWord += "_"
}
}
return guessedWord
}
mutating func playerGuessed(letter: Character) {
guessedLetters.append(letter)
if !word.contains(letter) {
incorrectMovesRemaining -= 1
}
}
}
Here is a simplified version of your code that you can compile in a playground:
struct Game {
var word: String
var formattedWord: String {
return "_" + word + "_"
}
}
let g1 = Game(word: "one")
let g2 = Game(word: "two")
let g3 = Game(word: "three")
print(Game.formattedWord)
Q1. If this compiled without an error, what you expect to be printed?
Your answer to Q1 shows a serious misunderstanding. Neither g1, g2, nor g3 are equal to Game, they are Games. If that compiled without error (which it doesn't), I would expect it to print "(Property)" or "(Getter)", much like this prints "(Function)":