重新初始化后,类变量保持不变

时间:2017-11-09 11:28:32

标签: ios swift xcode class

我正在做一个双人游戏的tic-tac-toe游戏。每当用户按下New Game按钮时,MultiPlayerGame类再次进行初始化。问题是它内部的变量(gameMatrixfirstPlayercellsLeft)保持不变。我在这些变量的声明中设置了一个断点,它们似乎重新启动,但每次我在初始化之前打印它们的那些变量的值,因此我的游戏无效。

//
//  MultiPlayerGame.swift
//  Tic Tac Toe
//
//  Created by Andrei Vataselu on 11/7/17.
//  Copyright © 2017 Andrei Vataselu. All rights reserved.
//

import Foundation
import UIKit



class MultiPlayerGame{

    enum playerTurn {
        case firstPlayer // valoarea 0 in gameMatrix
        case secondPlayer // valoarea 1 in gameMatrix
    }


    var turnToPlay : playerTurn
    var gameMatrix : [Int]
    var cellsLeft : Int

    static var game = MultiPlayerGame()

    private init(){
        self.turnToPlay = .firstPlayer

        // Prepara tabla pentru joc

        self.cellsLeft = 9

        self.gameMatrix = [2,2,2,
                           2,2,2,
                           2,2,2]


        for i in 0..<mpImages.count {
            mpImages[i].isHidden = true
            mpButtons[i].isHidden = false
        }

        mpNewGameButton.isHidden = true

        mpTurnLabel.text = "X turn"
        mpTurnLabel.isHidden = false

        mpWinningImg.isHidden = true
        mpWinningLabel.isHidden = true

    }

    static func getMultiplayerGame() -> MultiPlayerGame {
        return game
    }

    static func newGame(){
        game = MultiPlayerGame()
    }

    func actionCell(senderTag: Int,gameMatrixValue: Int, imageToChange: UIImage){
        gameMatrix[senderTag] = gameMatrixValue
        mpButtons[senderTag].isHidden = true
        mpImages[senderTag].image = imageToChange
        mpImages[senderTag].isHidden = false
        cellsLeft -= 1
     }

    func showEnding(imageToShow: UIImage){
        mpWinningImg.image = imageToShow
        mpWinningImg.isHidden = false
        mpTurnLabel.isHidden = true
        mpNewGameButton.isHidden = false

        if turnToPlay == .firstPlayer {
            mpWinningLabel.text = "X WINS"
        } else {
            mpWinningLabel.text = "O WINS"
        }
        mpWinningLabel.isHidden = false

        //disableButtons
        for i in 0..<mpImages.count {
            mpButtons[i].isHidden = true
        }

    }

    func endGame(winState: Int) {
        switch winState {
        case 1:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState1"))
        case 2:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState2"))

        case 3:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState3"))

        case 4:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState4"))

        case 5:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState5"))

        case 6:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState6"))

        case 7:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState7"))

        case 8:
            showEnding(imageToShow: #imageLiteral(resourceName: "winState8"))

        case 9:
            mpWinningLabel.text = "TIE"
            mpWinningLabel.isHidden = false
            mpNewGameButton.isHidden = false


        default: break
        }
    }

    func checkEndGame() {
        if gameMatrix[0] == gameMatrix[4] && gameMatrix[4] == gameMatrix[8] && gameMatrix[0] != 2 {
            endGame(winState: 7)
        } else if gameMatrix[2] == gameMatrix[4] && gameMatrix[4] == gameMatrix[6] && gameMatrix[2] != 2{
            endGame(winState: 8)
        } else if gameMatrix[0] == gameMatrix[3] && gameMatrix[3] == gameMatrix[6] && gameMatrix[0] != 2 {
            endGame(winState: 1)
        } else if gameMatrix[1] == gameMatrix[4] && gameMatrix[4] == gameMatrix[7] && gameMatrix[1] != 2{
            endGame(winState: 2)
        } else if gameMatrix[2] == gameMatrix[5] && gameMatrix[5] == gameMatrix[8] && gameMatrix[2] != 2{
            endGame(winState: 3)
        } else if gameMatrix[0] == gameMatrix[1] && gameMatrix[1] == gameMatrix[2] && gameMatrix[0] != 2 {
            endGame(winState: 4)
        } else if gameMatrix[3] == gameMatrix[4] && gameMatrix[4] == gameMatrix[5] && gameMatrix[3] != 2 {
            endGame(winState: 5)
        } else if gameMatrix[6] == gameMatrix[7] && gameMatrix[7] == gameMatrix[8] && gameMatrix[6] != 2{
            endGame(winState: 6)
        }
        else if cellsLeft == 0{
            endGame(winState: 9)
        }
    }

    func clickedCell(senderTag : Int) {
        if gameMatrix[senderTag] == 2 && cellsLeft != 0{
            if turnToPlay == .firstPlayer{
                actionCell(senderTag: senderTag, gameMatrixValue: 0, imageToChange: #imageLiteral(resourceName: "x"))
                checkEndGame()
                turnToPlay = .secondPlayer
                mpTurnLabel.text = "O turn"
            } else {
                actionCell(senderTag: senderTag, gameMatrixValue: 1, imageToChange: #imageLiteral(resourceName: "zero"))
                checkEndGame()
                turnToPlay = .firstPlayer
                mpTurnLabel.text = "X turn"
            }

    }
}
}

这是我在ViewController中使用它的方式

var game = MultiPlayerGame.getMultiplayerGame()

@IBAction func buttonPressed(_ sender: UIButton) {
        game.clickedCell(senderTag: sender.tag)
    }

    @IBAction func newGameButtonPressed(_ sender: Any) {
        MultiPlayerGame.newGame()
    }

1 个答案:

答案 0 :(得分:2)

问题是,您的变量game 有一个类静态变量的副本,当您调用newGame时,静态变量会发生变化,但您的var game不会#39;吨。

致电newGame后,需要重新分配您的游戏变量game = MultiPlayerGame.getMultiplayerGame()

我做了一个简短的例子来说明我的意思,你可以在操场上重现它:

class Game {
    var a: Int

    static var game = Game()

    private init() {
        a = 0
    }

    static func newGame() {
        game = Game()
    }
}

var g = Game.game
g.a = 2

Game.newGame()
print(g.a)                  // value is 2, but you are probably expecting 0

var newGame = Game.game
print(newGame.a)            // value is 0, as it should
g = Game.game
print(g.a)                  // value is 0, as it should

即使控制器内部有var game = MultiPlayerGame.getMultiplayerGame(),只有在第一个实例化控制器时才会调用它。

您可以将getter更改为自定义并始终获取游戏的新实例,如下所示:

var game: MultiPlayerGame {
   get {
       return MultiPlayerGame.getMultiplayerGame()
   }
}