在开始之前,这个问题已经有一段时间了,但是我认为答案并不令人满意(GKMinmaxStrategist modifies model after return of best move)
我正在尝试构建一种具有两种玩家类型(国王,敌人)的简单棋盘游戏。作为其中的一部分,我试图实现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
分别是单独的实例。我完全可以确定问题是在apply方法中,moveToken(move: move)
是应用于实际游戏板而不是副本,但是我不明白为什么(要确认我刚进入游戏板就打印了游戏板,在退出功能之前,打印效果会有所不同,但是我不希望每次调用此方法时主板都会发生变化。否则,它似乎可以正常工作,并且会返回明智的选择。
任何帮助将不胜感激!
答案 0 :(得分:1)
我怀疑问题出在您的setGameModel
函数中:
func setGameModel(_ gameModel: GKGameModel) {
if let board = gameModel as? Board {
gameBoard = board.gameBoard
}
}
我的猜测是board.gameBoard
是类而不是结构,这意味着两种游戏模型都引用同一块棋盘。然后,GKMinmaxStrategist
进行计算时,它将更改该类,并因此更改当前的游戏模型。
希望这会有所帮助!