swift - GKMinmaxStrategist 不返回任何 Action

标签 swift gameplay-kit gkminmaxstrategist

我的 main.swift 中有以下代码:

let strategist = GKMinmaxStrategist()
strategist.gameModel = position
strategist.maxLookAheadDepth = 1
strategist.randomSource = nil

let move = strategist.bestMoveForActivePlayer()

...其中 position 是我的 GKGameModel 子类 Position 的实例。运行此代码后,movenilbestMoveForPlayer(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/

相关文章:

ios - 如何创建一个动态更改其高度以适应其内容的表格 View 单元格?

ios - 使用 react-native-navigation 将 React Native 应用程序与现有的 iOS 应用程序集成

swift - 我可以使用 swift 使 self.entity 成为组件中某些功能的非可选吗?

ios - 如何使用 gameplaykit 在编辑器中向 Sprite 添加组件

ios - xcode 8 beta 4 中的 GKBehaviour 使 gkagent 位置变得疯狂

swift - 从哪里开始使用 GKMinmaxStrategist?

ios - 如何使符合已定义协议(protocol)的 UITableViewCells 出队

Swift 等待关闭线程完成