GKMinmaxStrategist modifies model after return of best move

試著忘記壹切 提交于 2019-12-12 05:14:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!