Ход компьютера в крестики-нолики

249
13 мая 2018, 06:00

Как реализовать ход компьютера (не в плане реализации логики хода компьютера), а именно логику вызова его хода? Т.е. после события моего хода, должно вызваться событие (или метод) хода компьютера, вот я не могу догнать как это сделать.

Выглядит всё примерно так. У меня имеется размеченный грид 3*3 (как игровое поле). когда я делаю клик по какому-то квадратику, то происходит событие нажатия кнопки мыши и у меня запускается метод проверки (пустая ли клеточка) и если она пустая, рисуется крестик или нолик.

Далее у меня меняется свойство - кто должен ходить и когда оно меняется срабатывает метод - ходит компьютер.

Проблема в том, что свойство меняется в обработчике событий и соответственно метод хода компьютера срабатывает внутри события тоже (т.е. событие ещё не отработало). И когда всё это отрабатывает, происходит отрисовка и крестика и нолика одновременно. А я хочу сделать так, кликнул я в область, произошёл мой ход, нарисовался крестик. Затем например прошло 2 сек. (якобы компьютер подумал) и начал ходить компьютер, т.е. отрисовался нолик.

Answer 1

Допустим, у вас имеется некий метод, рассчитывающий лучший ход и возвращающий ячейку, в которую нужно сыграть компьютеру:

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

Создайте из этого метода задачу:

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

Теперь нам нужно написать задачу ожидания, поскольку штатный Task.Delay возвращает непараметризированную задачу, его здесь использовать неудобно, поэтому я написал такой простой хелпер:

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);
}

Используем этот хелпер для создания задачи ожидания, возвращающей фиктивное значение (которое мы использовать не будем):

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

Теперь просто надо дождаться завершения обеих задач (если расчет будет выполнен быстро, то мы всё равно прождем эти 500 мс, если расчет займет свыше 500 мс, то мы прождем до его завершения), и взять результат первой задачи:

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

Всё!

READ ALSO
как к visual studio c# подключить базы данных SQL Server”

как к visual studio c# подключить базы данных SQL Server”

как к visual studio c# подключить базы данных SQL Server?

243
Конфигурационные файлы в Stateless/Statefull сервисов Azure Fabric Services

Конфигурационные файлы в Stateless/Statefull сервисов Azure Fabric Services

Не могли бы вы рассказать, какие есть конфиги подходящие для хранения кастомных ветвей вида

214
MiFare 1K запись данных, Exeption

MiFare 1K запись данных, Exeption

Пытаюсь записать данные на карту MiFare Classic 1K, выдаёт исключение Exeption:Unable to login in sector 2 with key key B

192
Как сделать чтобы кнопка нажималась при прикосновении? unity

Как сделать чтобы кнопка нажималась при прикосновении? unity

Практикуюсь в Unity и на данный момент хочу создать пианино

214