I've built a strategy game and implemented a Gameplay kit AI for it. The AI can potentially take several moves per turn. Since the GKMinMaxStrategist
gives one best move per call, I have put the method bestMoveForPlayer()
inside tileForAIMove()
in a while let loop.
Every implementation I have seen puts the method in a DispatchQueue.global()
separate thread so I attempted to match this. To actually execute the move, a map change is required so I execute it on the main thread. Unfortunately this causes weird behaviors which lead to BAD ACCESS errors since the while loop can execute multiple times inside the global thread before the main thread executes the previous move.
I have tried several variations, but at this point can't figure out how to effectively use threads here. This is my current code:
func startAIMove() {
DispatchQueue.global().async {[unowned self] in
let strategistTime = CFAbsoluteTimeGetCurrent()
var timeCieling = 2.0
while let move = self.tileForAIMove() {
DispatchQueue.main.async {[unowned self] in
self.makeAIMove(with: move.tile, position: move.position)
//Keep going until all the moves for this possible turn are made.
self.checkForPlayerLosing()
if let currentPlayer = self.gameModel!.activePlayer! as? Player {
if currentPlayer.availableLevel3! + currentPlayer.availableLevel2! + currentPlayer.availableLevel1! + currentPlayer.availableCounters! == 0{
//No valid moves left so we transition to next player.
DispatchQueue.main.asyncAfter(deadline: .now() + timeCieling){ [unowned self] in
print("EndTurn \(self.gameModel!.activePlayer!.playerId)")
self.advanceTurnToNextPlayer()
}
}
}
}
}
}
}
Essentially what I am asking simply put is, how can I make this thread code better.
Thanks!