问题
I implemented GKGameModel, GKGameModelPlayer and GKGameModelUpdate protocols in my corresponding classes. After I ask for best move strategist changes my model's board. I understand how it works, making copies of model and tried all moves, but I thought that my "main" model (from copies are made) won't be affected.
Here is what I have:
let strategist = GKMinmaxStrategist()
strategist.maxLookAheadDepth = 0
strategist.randomSource = GKRandomSource()
//my model. game is my auxiliary class, players is an array of GKGameModelPlayer
let gameTable = GameTable(game: game, players: [player1, player2])
strategist.gameModel = gameTable
print(gameTable.board)
let moveForActivePlayer = strategist.bestMoveForActivePlayer()
print(gameTable.board)
Output log:
//first print:
—————————————————
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | |X|O| | | |
| | | |O|X| | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
—————————————————
//second print (after bestMove)
—————————————————
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | |O|O| | | |
| | | |O|O| | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
—————————————————
This is a reversi (othello) game by the way.
I do not understand why our model is changed... I thought that copies would but the main model will be ready for best move to apply.
What I'm doing wrong here? Here is my model's copy method:
func copy(with zone: NSZone? = nil) -> Any {
let table = GameTable(game: self.game)
table.setGameModel(self)
return table
}
func setGameModel(_ gameModel: GKGameModel) {
let table = gameModel as! GameTable
self.board = table.board.copy() //board is a class with array of every cell.
//It's responsible for game state.
//copy() here just returns new instance with same values for cells
self.players = table.players
self.activePlayer = table.activePlayer
}
What I'm doing here wrong? Thanks in advance.
Edit
I found the problem in my code and it was related to what Tim said in his answer. You need to check if you actually make a copy (or create new object for Swift). I missed this in one place and that was my mistake.
回答1:
It looks like the problem is that you need to do a deep copy on your array. Otherwise, the states of the objects in your board array will be changed even in the copied version.
According to Apple (https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html), you can easily do a deep copy with
NSArray *deepCopyArray=[[NSArray alloc] initWithArray:someArray copyItems:YES];
Only, I assume, in Swift 😉
来源:https://stackoverflow.com/questions/44486141/gkminmaxstrategist-modifies-model-after-return-of-best-move