Swift 4 - GKMinmaxStrategist 修改实际游戏模型
Swift 4 - GKMinmaxStrategist Modifying Actual Game Model
在我开始之前,这个问题已经有人问过了,但我认为答案并不令人满意()
我正在尝试构建一个具有两种玩家类型(国王、敌人)的简单棋盘游戏。作为其中的一部分,我正在尝试实现 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)
被应用到实际的游戏板而不是副本,但我不明白为什么(确认我在进入后刚打印了游戏板,只是在退出函数之前,打印结果有所不同,而我不希望主板在调用此方法时发生变化)。否则它似乎工作正常并且它 returns 一个明智的举动。
如有任何帮助,我们将不胜感激!
我怀疑问题出在您的 setGameModel
函数中:
func setGameModel(_ gameModel: GKGameModel) {
if let board = gameModel as? Board {
gameBoard = board.gameBoard
}
}
我的猜测是 board.gameBoard
是一个 class 而不是一个结构,这意味着两个游戏模型都引用同一个面板。然后,当 GKMinmaxStrategist
进行计算时,它会更改 class 并因此更改当前游戏模型。
希望对您有所帮助!
在我开始之前,这个问题已经有人问过了,但我认为答案并不令人满意(
我正在尝试构建一个具有两种玩家类型(国王、敌人)的简单棋盘游戏。作为其中的一部分,我正在尝试实现 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)
被应用到实际的游戏板而不是副本,但我不明白为什么(确认我在进入后刚打印了游戏板,只是在退出函数之前,打印结果有所不同,而我不希望主板在调用此方法时发生变化)。否则它似乎工作正常并且它 returns 一个明智的举动。
如有任何帮助,我们将不胜感激!
我怀疑问题出在您的 setGameModel
函数中:
func setGameModel(_ gameModel: GKGameModel) {
if let board = gameModel as? Board {
gameBoard = board.gameBoard
}
}
我的猜测是 board.gameBoard
是一个 class 而不是一个结构,这意味着两个游戏模型都引用同一个面板。然后,当 GKMinmaxStrategist
进行计算时,它会更改 class 并因此更改当前游戏模型。
希望对您有所帮助!