Before I start, this question has already been asked a while ago but I don't believe the answer is satisfactory (GKMinmaxStrategist modifies model after return of best move)
I am trying to build a straightforward board game with two player types (king, enemy). As part of that I am trying to implement the GKMinmaxStrategist and the problem is that it keeps modifying the actual game model rather than simulating moves on the copy.
Let me start by showing some code:
//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
...
As mentioned in the code above, copy
and self
turn out to be separate instances. Im fairly certain the problem is in the apply method where moveToken(move: move)
is being applied to the actual game board rather than the copy, but I don't understand why (To confirm I have printed the game board just after entering and just before exiting the function and the prints differed, whereas I wouldn't expect the main board to change whenever this method is called). Otherwise it seems to work fine and it returns a sensible move.
Any help would be much appreciated!
I suspect the problem is in your
setGameModel
function:My guess is that
board.gameBoard
is a class and not a struct, which means both game models reference the same board. Then, when theGKMinmaxStrategist
does its computation, it changes that class and therefore the current game model.Hope this helps!