How to implement the course of the computer (not in terms of the implementation of the logic of the course of the computer), namely, the logic of calling its course? Those. after the event of my move, the event (or method) of the computer should trigger, so I can not catch up with how to do it.

It looks like this. I have a marked 3 * 3 grid (like a playing field). when I click on a square, a mouse click event occurs and I run a check method (empty cell) and if it is empty, a cross or a zero is drawn.

Next, my property changes - who should walk and when it changes, the method works - the computer goes.

The problem is that the property changes in the event handler and, accordingly, the computer's running method works inside the event too (that is, the event has not yet worked). And when all this works, there is a drawing of a cross and a zero at the same time. And I want to do so, I clicked into the area, there was my move, I drew a cross. Then for example 2 seconds passed. (supposedly the computer thought) and began to walk the computer, i.e. drawn zero.

  • Just make a counter. On even you, on odd PCs. - sapeg
  • @sapeg Well, I was like (I clicked to the desired area, the click event was triggered and everything was redrawn to me), now I need to somehow trigger the progress of the computer. Here's how to do it? I do not ask at what point I call the computer, I ask how do I do? - alladuh
  • one
    Write the progress code of the computer and call it at the right time. - vp_arth
  • Just after the player's move, call the AI ​​move method: github.com/AndrewNowosad/Max8.NET/blob/… - Andrey NOP
  • Banal timer var timer = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 2) } , which will process the timer.Tick += (object sender, EventArgs e) => { timer.Stop(); AITurn(); SwapTurn(); } timer.Tick += (object sender, EventArgs e) => { timer.Stop(); AITurn(); SwapTurn(); } timer.Tick += (object sender, EventArgs e) => { timer.Stop(); AITurn(); SwapTurn(); } . - Alex Krass

1 answer 1

Suppose you have a method that calculates the best move and returns the cell to which the computer needs to play:

 public Cell CalculateBestMove(...) { ... } 

Create a task from this method:

 var calcTask = Task.Run(() => CalculateBestMove(...)); 

Now we need to write a wait task, because a regular Task.Delay returns an Task.Delay task, which is inconvenient to use here, so I wrote such a simple helper:

 class TplHelpers { public static Task<T> Delay<T>(T returnValue, int milliseconds) { var tcs = new TaskCompletionSource<T>(); var timer = new System.Timers.Timer(milliseconds) { AutoReset = false }; timer.Elapsed += delegate { timer.Dispose(); tcs.SetResult(returnValue); }; timer.Start(); return tcs.Task; } public static Task<T> Delay<T>(int milliseconds) => Delay(default(T), milliseconds); } 

Use this helper to create a wait task that returns a dummy value (which we will not use):

 var delayTask = TplHelpers.Delay<Cell>(500); 

Now we just have to wait for the completion of both tasks (if the calculation is completed quickly, we still wait for 500 ms, if the calculation takes over 500 ms, then we wait until it is completed), and take the result of the first task:

 var cell = (await Task.WhenAll(calcTask, delayTask))[0]; 

Everything!