Search code examples
swiftsprite-kitartificial-intelligencenstimer

How to run timer and AI logic in Swift simultaneously


I have an NSTimer() and an AI logic for a board game. The AI logic takes long time to process about 3 to 5 seconds(which is ok). When the program is executing the AI logic, the NSTimer doesn't fire until the AI logic finished it's execution.

This is how i started the timer during the initial stage of the game.

    public var timer = NSTimer()

...

    let timeSelector:Selector = "timerFired"
    if self.useTime {
       timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: timeSelector, userInfo: nil, repeats: true)
    }

I added the AI logic in Update of an SKScene so that when it detects it is his turn, he will start checking for available moves

override func update(currentTime: CFTimeInterval) {
      if gameStatus.playerTurn == "AI" && !aiThiking {
         aiThiking = true
         aIPlayer.aiCheckAvaialbleMoves()
         // executeMove
         // change Turn
         aiThiking = false
      }

My question is, is it possible to let the AI logic execute and let the timer still running at the same time?


Solution

  • Your problem seems to be that aIPlayer.aiCheckAvailableMoves() freezes the app as long as it takes to execute, so NSTimer does not work as it should. You can use different threads to avoid this:

    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        aIPlayer.aiCheckAvaialbleMoves()
    }
    

    This code runs this function in a new thread and when the code ended, the thread is closed automatically.

    You could use completion blocks to know exactly when the function ended. Here is an example:

    func aiCheckAvailableMoves(completion : (result : BOOL) -> Void) {
       dispatch_async(dispatch_get_global_queue(priority, 0)) {
           //Do your code normally
    
           //When you have finished, call the completion block (like a return)
           completion(true)
       }
    }
    

    And then, from your update: you will get when the function ended (please note here there is no dispatch_async):

    aIPlayer.aiCheckAvailableMoves(){
        //Finished checking moves, maybe schedule again?
    }
    

    Be careful with threads, as they can cause unwanted behaviour or/and crashes!