Artificial Intelligence and Simultaneous Screen Updates

I am trying to incorporate an artificial intelligence (AI).

Hypothetically, lets say the game is chess. So when it is the AI’s turn, it is okay that the human player has to wait while the AI calculates what move to make.

Right now it takes 10-30 seconds to complete the code for the AI to make a decision depending on the layers of complexity I add to the AI decision making.

My problem is that the screen does not update during this block of code; meaning it feels like the game has locked-up or is frozen. Reading some of the Corona documentation, I realized that screen updates do not happen until all the code has finished running.

So any sprite or “transition.to” animation that I use doesn’t really do anything because the screen doesn’t update until the code has finished. And when the code has finished running, that means the AI’s turn is over and I don’t need that animation anymore.

However I want to give the human player some visual feedback that the game is still running and that the AI is “thinking”. Some sort of animation on screen, like a ticking clock for example.

Is there a way for me to update the screen and have the AI code run in the background at the same time?

Thanks.

[import]uid: 37876 topic_id: 10457 reply_id: 310457[/import]

Im not sure if this will work, but I think it should…
Try using this periodically in your code…
[lua]timer.performWithDelay(1,function()
**Code you want to perform after screen update**
end,1)[/lua]

for ex… as far as I’m aware the following should happen
[lua]…
x = 1+1 --Code executed before screen refresh
timer.performWithDelay(…) --Code executed after screen refresh
y = x+x --Code executed before screen refresh
…[/lua]
Hope it works :smiley: [import]uid: 34945 topic_id: 10457 reply_id: 38115[/import]

Have you tried using a sprite animation vs. a normal transition? You could start the sprite “clock ticking” or whatever before your AI routine and pause it afterward. This should continue running (animating) while the AI is being calculated.

Another option might be to use a physics object and just starting it on a rotation velocity. I see no reason why Corona would stop calculating its rotation during the AI, but I haven’t tested such things before…

Brent
[import]uid: 9747 topic_id: 10457 reply_id: 38118[/import]

Why not try http://developer.anscamobile.com/reference/index/nativesetactivityindicator [import]uid: 48521 topic_id: 10457 reply_id: 38170[/import]

The key is to use LUA coroutines here.

Coroutines are kind of “multi-threading” (not really, but it behaves similar), which means you can do several tasks the same time.

By using coroutines, you can leave a function at any time and resume this function exactly at the point where you left it the last time. Assume you have a function that takes 30 seconds to complete. By calling it as a coroutine, you can jump out of this function every, say 33 millisecs, to do your enter frame stuff (screen updates, animations etc.) and then resume it.

"Coroutines allow us to execute several tasks at once. This is done in a controlled manner by passing control to each routine and waiting until the routine says it has finished. We can reenter the routine to continue at a later time and by doing this repeatedly we achieve multi-tasking. "

LUA Coroutines Tutorial

Keep in mind that using coroutines will make the processing of your AI a little bit slower (since you also do enter frame stuff then while calculating), but it avoids freezing your app.

To further speed up your AI, you should also implement game tree searching techniques like alpha beta pruning and decent move ordering. [import]uid: 10504 topic_id: 10457 reply_id: 38180[/import]

Yeah, coroutines are definitely the way to go :smiley: [import]uid: 34945 topic_id: 10457 reply_id: 38198[/import]

Excellent! Thanks for all the help! Coroutines seem to be solution.

I basically pause the AI code every 30ms, then run a timer with 1ms delay. Here is a highly summarized version of the code:

function startRoutine()  
  
 local co = coroutine.create(function()  
 local startTime = system.getTimer()  
 --ai goes here  
 --then when it reaches the main decision-making loop  
 -- ,I include this within the loop:  
 if (system.getTimer - startTime) \> 30 then  
 timer.performWithDelay(1,startRoutine)  
 coroutine.yield()  
 end  
 end)  
  
 coroutine.resume(co)  
end  
  

So unless there is a better way to do do the actual screen updating (instead of doing the timer.performWithDelay), I think that I am all set.

Thanks! [import]uid: 37876 topic_id: 10457 reply_id: 38323[/import]