1

在我开始之前,这个问题已经被问过了一段时间,但我不相信答案是令人满意的(GKMinmaxStrategist 在返回最佳移动后修改模型

我正在尝试构建一个具有两种玩家类型(国王、敌人)的简单棋盘游戏。作为其中的一部分,我正在尝试实现 GKMinmaxStrategist,问题在于它不断修改实际的游戏模型,而不是在副本上模拟移动。

让我从显示一些代码开始:

    //From Board Class
    func moveToken(move: Move) {
        let tokenAtOrigin = tokenAt(at: move.origin)
        gameBoard[move.destination.row, move.destination.column] = tokenAtOrigin
        tokenAtOrigin?.row = move.destination.row
        tokenAtOrigin?.column = move.destination.column
        gameBoard[move.origin.row, move.origin.column] = nil
    }

    //Extension to Board for strategist implementation
    extension Board: GKGameModel {

        func copy(with zone: NSZone? = nil) -> Any {
            let copy = Board()
            copy.setGameModel(self)
            print(copy === self)   //returns False
            return copy
        }

        func setGameModel(_ gameModel: GKGameModel) {
            if let board = gameModel as? Board {
                gameBoard = board.gameBoard
            }
        }

        func apply(_ gameModelUpdate: GKGameModelUpdate) {
            guard  let move = gameModelUpdate as? Move else {
                return
            }
            moveToken(move: move)
            currentPlayer = currentPlayer.opponent
        }
    }

    //GameViewController
    var board = Board()
    strategist.gameModel = board
    ...

正如上面的代码中提到的,copy结果self是单独的实例。我相当确定问题出在moveToken(move: move)应用于实际游戏板而不是副本的应用方法中,但我不明白为什么(确认我在进入后和退出功能之前打印了游戏板,并且印刷品不同,而我不希望每当调用此方法时主板会发生变化)。否则它似乎工作正常,它返回一个明智的举动。

任何帮助将非常感激!

4

1 回答 1

1

我怀疑问题出在你的setGameModel函数中:

func setGameModel(_ gameModel: GKGameModel) {
    if let board = gameModel as? Board {
        gameBoard = board.gameBoard
    }
}

我的猜测是这board.gameBoard是一个类而不是一个结构,这意味着两个游戏模型都引用了同一个棋盘。然后,当GKMinmaxStrategist它进行计算时,它会更改该类,从而更改当前的游戏模型。

希望这可以帮助!

于 2019-04-12T23:26:25.170 回答