我的 main.swift
中有以下代码:
let strategist = GKMinmaxStrategist()
strategist.gameModel = position
strategist.maxLookAheadDepth = 1
strategist.randomSource = nil
let move = strategist.bestMoveForActivePlayer()
...其中 position
是我的 GKGameModel
子类 Position
的实例。运行此代码后,move
为nil
。 bestMoveForPlayer(position.activePlayer!)
也会导致 nil
(但 position.activePlayer!
会导致 Player
对象).
但是,
let moves = position.gameModelUpdatesForPlayer(position.activePlayer!)!
导致可能移动的非空数组。来自 Apple 的文档(关于 bestMoveForPlayer(_:)
):
Returns nil if the player is invalid, the player is not a part of the game model, or the player has no valid moves available.
据我所知,情况并非如此,但该函数仍返回 nil
。这里会发生什么?
如果有任何帮助,这是我对 GKGameModel
协议(protocol)的实现:
var players: [GKGameModelPlayer]? = [Player.whitePlayer, Player.blackPlayer]
var activePlayer: GKGameModelPlayer? {
return playerToMove
}
func setGameModel(gameModel: GKGameModel) {
let position = gameModel as! Position
pieces = position.pieces
ply = position.ply
reloadLegalMoves()
}
func gameModelUpdatesForPlayer(thePlayer: GKGameModelPlayer) -> [GKGameModelUpdate]? {
let player = thePlayer as! Player
let moves = legalMoves(ofPlayer: player)
return moves.count > 0 ? moves : nil
}
func applyGameModelUpdate(gameModelUpdate: GKGameModelUpdate) {
let move = gameModelUpdate as! Move
playMove(move)
}
func unapplyGameModelUpdate(gameModelUpdate: GKGameModelUpdate) {
let move = gameModelUpdate as! Move
undoMove(move)
}
func scoreForPlayer(thePlayer: GKGameModelPlayer) -> Int {
let player = thePlayer as! Player
var score = 0
for (_, piece) in pieces {
score += piece.player == player ? 1 : -1
}
return score
}
func isLossForPlayer(thePlayer: GKGameModelPlayer) -> Bool {
let player = thePlayer as! Player
return legalMoves(ofPlayer: player).count == 0
}
func isWinForPlayer(thePlayer: GKGameModelPlayer) -> Bool {
let player = thePlayer as! Player
return isLossForPlayer(player.opponent)
}
func copyWithZone(zone: NSZone) -> AnyObject {
let copy = Position(withPieces: pieces.map({ $0.1 }), playerToMove: playerToMove)
copy.setGameModel(self)
return copy
}
如果有任何其他我应该显示的代码,请告诉我。
最佳答案
您需要在应用 或取消 移动后更改activePlayer
。
在您的情况下,这将是 playerToMove
。
The player whose turn it is to perform an update to the game model. GKMinmaxStrategist assumes that the next call to the applyGameModelUpdate: method will perform a move on behalf of this player.
当然还有:
Function
applyGameModelUpdate
Applies a GKGameModelUpdate to the game model, potentially resulting in a new activePlayer. GKMinmaxStrategist will call this method on a copy of the primary game model to speculate about possible future moves and their effects. It is assumed that calling this method performs a move on behalf of the player identified by the activePlayer property.
func applyGameModelUpdate(gameModelUpdate: GKGameModelUpdate) {
let move = gameModelUpdate as! Move
playMove(move)
//Here change the current Player
let player = playerToMove as! Player
playerToMove = player.opponent
}
您的 unapplyGameModelUpdate
实现也是如此。
另外,请特别注意您的setGameModel
实现,因为它应该复制模型中的所有 数据。这包括 activePlayer
Sets the data of another game model. All data should be copied over, and should not maintain any pointers to the copied game state. This is used by the GKMinmaxStrategist to process permutations of the game without needing to apply potentially destructive updates to the primary game model.
关于swift - GKMinmaxStrategist 不返回任何 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34616857/