我正在开发一个两人策略棋盘游戏,可以选择与CPU对抗,并且我正在使用GKMinmaxStrategist来给CPU玩家一些头脑。就背景而言,游戏中有两个“派别”(国王(King,Enemy))和一位扮演国王的国王总是开始。
现在,我设法实现了战略家,并且如果我与CPU对抗King并迈出第一步,那么它就可以工作。但是,当我扮演敌人的角色并且CPU必须先采取行动(扮演King角色)时,这样做的效果还不够奇怪。看来,在调用策略家的bestMove方法之后,它不会调用任何基本的模拟方法,例如isWin,apply,score等。
我曾尝试更改规则,以使敌人始终启动,但再次无效,而当我扮演国王并迈出第一步时(如上所述),它确实为敌人吐出了动作。< / p>
此外,我没有使用策略师,而是简单地从所有可能的动作中随机选择了动作,只是为了看看基于回合的逻辑是否有效。对于两个派别,它都会在何时以及如何发生变化中移动。
所以,这第一步,不管是哪个派别出现的问题,我都无法弄清楚为什么会这样。 有没有人遇到过类似的问题,或者对为什么会这样有任何聪明的主意吗?
任何帮助将不胜感激。
这是游戏模型的扩展,其中包括战略家以及管理游戏玩法的GameVC。
extension Board: GKGameModel {
var activePlayer: GKGameModelPlayer? {
return currentPlayer
}
var players: [GKGameModelPlayer]? {
return Player.allPlayers
}
func copy(with zone: NSZone? = nil) -> Any {
let copy = Board()
copy.setGameModel(self)
return copy
}
func setGameModel(_ gameModel: GKGameModel) {
if let board = gameModel as? Board {
tokens = board.tokens
}
}
func isWin(for player: GKGameModelPlayer) -> Bool {
guard let player = player as? Player else {
return false
}
if let winner = isWinner() {
return player.player == winner
} else {
return false
}
}
func gameModelUpdates(for player: GKGameModelPlayer) -> [GKGameModelUpdate]? {
guard let player = player as? Player else {
return nil
}
if isWin(for: player) {
return nil
}
return allPossibleMoves(faction: player.player)
}
func apply(_ gameModelUpdate: GKGameModelUpdate) {
guard let move = gameModelUpdate as? Move else {
return
}
performMove(move: move)
currentPlayer = currentPlayer.opponent
}
func score(for player: GKGameModelPlayer) -> Int {
guard let player = player as? Player else {
return Score.none.rawValue
}
if isWin(for: player) {
return Score.win.rawValue
} else {
return Score.none.rawValue
}
}
}```
```class GameViewController: UIViewController, BoardDelegate {
var scene: GameScene!
var board: Board!
var strategist: GKMinmaxStrategist!
override func loadView() {
self.view = SKView(frame: UIScreen.main.bounds)
}
override func viewDidLoad() {
super.viewDidLoad()
let skView = view as! SKView
skView.isMultipleTouchEnabled = false
skView.isUserInteractionEnabled = false
scene = GameScene(size: skView.bounds.size)
scene.scaleMode = .aspectFill
board = Board()
board.delegate = self
scene.board = board
scene.handleUserMove = handleUserMove
scene.fillBoardWithSprites()
strategist = GKMinmaxStrategist()
strategist.maxLookAheadDepth = 1
strategist.randomSource = GKARC4RandomSource()
strategist.gameModel = board
skView.presentScene(scene)
initiateMove()
}
//Check if user`s turn
func checkUserTurn() -> Bool {
return board.userPlayer.player == board.currentPlayer.player
}
//Change turn of players between user and CPU
func changeTurn() {
board.currentPlayer = board.currentPlayer.opponent
}
//Find best move for CPU using GKMinmaxStrategist
func chooseCpuMove() -> Move? {
if let move = strategist.bestMove(for: board.currentPlayer) as? Move {
print("found move")
return move
}
return nil
}
//Perform CPU move
func handleCpuMove(move: Move) {
scene.animateMove(move: move) {}
board.performMove(move: move)
board.moved()
}
//Check whose turn it is and either turn on user interaction or start CPU move
func initiateMove() {
print("initiating")
self.view.isUserInteractionEnabled = checkUserTurn()
if checkUserTurn() {
//Wait for user to move
} else {
print("checking cpuMove")
if let cpuMove = chooseCpuMove() {
handleCpuMove(move: cpuMove)
}
}
}
func handleUserMove(move: Move, bool: Bool) {
if board.isMoveAllowed(move: move) {
scene.animateMove(move: move) {}
board.performMove(move: move)
board.moved()
}
}
func currentPlayerDidMove(board: Board) {
changeTurn()
if board.isWinner() != nil {
board.endGame()
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.initiateMove()
}
}
}
func gameDidEnd(board: Board) {
self.view.isUserInteractionEnabled = false
UserDefaults.standard.set(board.currentPlayer.player.name, forKey: "winner")
AppDelegate.shared.rootViewController.gameOverScreen()
}
}```