2016-01-05 24 views
11

を返しません。このコードを実行すると、movenilになります。 bestMoveForPlayer(position.activePlayer!)nilになります(但しposition.activePlayer!の結果はPlayerになります)。しかしながらGKMinmaxStrategistは、私は私の<code>main.swift</code>に次のコードを持っている任意の移動

、可能な動きの非空の配列に

let moves = position.gameModelUpdatesForPlayer(position.activePlayer!)! 

結果。 Appleのマニュアル(bestMoveForPlayer(_:)について):

プレーヤーが無効であるか、プレーヤーがゲームモデルの一部でないか、プレーヤーが有効な移動がない場合はnilを返します。

私が知る限り、これは該当しませんが、関数はまだnilを返します。ここで何が起こっているのでしょうか?

は、それがどんな助けになることができた場合は、ここでGKGameModelプロトコルの私の実装です:

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

+0

** maxLookAheadDepth **を増やしてみましたか? –

+0

私は持っていますが、違いはありません。 –

+0

私は理論を持っています、あなたのplayMove()の実装を追加して、自分の理論が正しいかどうか確認できますか? –

答えて

2

あなたが変更する必要があります。 あなたの場合はplayerToMoveになります。

ゲームモデルを更新するターンを持つプレイヤー。 GKMinmaxStrategistは、次回のapplyGameModelUpdate:メソッドの呼び出しでこのプレーヤーに代わって移動が行われると想定しています。

と、当然の:applyGameModelUpdateが潜在的に新しいactivePlayerその結果、ゲームのモデルにGKGameModelUpdateを適用

機能。 GKMinmaxStrategistは、可能な将来の動きとその影響について推測するために、プライマリゲームモデルのコピーでこのメソッドを呼び出します。このメソッドを呼び出すと、activePlayerプロパティで識別されるプレーヤに代わって移動が行われるものとします。

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

別のゲームモデルのデータを設定します。すべてのデータはコピーされ、コピーされたゲーム状態へのポインタは保持されません。これは、GKMinmaxStrategistによって、潜在的に破壊的な更新をプライマリゲームモデルに適用する必要なしに、ゲームの順列を処理するために使用されます。

+0

私の 'playMove(_ :)'関数は 'playerToMove'を変更します(具体的には、' playerToMove'のゲッターの中で使われる 'ply'変数をインクリメントします)。 –

+0

なぜ私はこれまでに試していなかったのか分かりませんが、質問で示した8つの関数の中にブレークポイントを設定し、 'bestMoveForActivePlayer()'はそれらのうちの1つだけを呼び出すことはありません。 'activePlayer'のゲッターを2回呼び出すだけです(これは最初のプレーヤーです)。 –

0

私は同じ問題がありました。返される.activePlayerインスタンスのいずれかを返す必要があります返された.players.playerIdと一致する新しいインスタンスを返すだけでは不十分です。

関連する問題