Как принудительно обновить пользовательский интерфейс в Swift? - PullRequest
0 голосов
/ 28 мая 2019

Я использую swift для разработки игры в шахматы. Когда компьютер играет сам, дисплей не обновляется, когда ход завершается, пока он не выходит из цикла (в этом случае игра заканчивается).

Я попытался отправить его в фоновую очередь, чтобы сгенерировать перемещение, и отправить его обратно в основную очередь, чтобы выполнить перемещение и обновить отображение. Хотя это, кажется, помогает обновить отображение, но у меня нет возможности предсказать завершение каждой фоновой очереди. Это портит порядок ходов.

Есть ли лучший способ заставить компьютер играть самому и правильно обновлять дисплей после каждого хода?

while chessGame.checkmate != true {
    DispatchQueue.global(qos: .background).async {
        let bestMove = chessAI.findBestMove(depth : chessGame.searchDepth)
        if bestMove != nil {
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
                chessMove.makeMove(m : bestMove!)
                self.boardView.setNeedsDisplay()
            }
        } else {
            print("CheckMate!")
            chessGame.checkmate = true
        }
    }
}

1 Ответ

0 голосов
/ 28 мая 2019

Вы можете немедленно вызвать отображение (позвонив по номеру displayIfNeeded), но это не поможет.

Проблема в том, что цикл while не делает пауз между итерациями: он просто продолжает цикл с максимальной скоростью. Таким образом, цикл while является плохой стратегией.

Вместо этого используйте рекурсию. Это дает вам контроль над тем, когда делать следующую итерацию, в ваших руках, а именно, вы делаете рекурсию после задержки. Это цикл, в котором вы можете сделать паузу между итерациями.

псевдокод:

func nextMove() {
    DispatchQueue.global(qos: .background).async {
        let bestMove = chessAI.findBestMove(depth : chessGame.searchDepth)
        if bestMove != nil {
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) { // or whatever
                chessMove.makeMove(m : bestMove!)
                self.boardView.setNeedsDisplay()
                if chessGame.checkmate != true {
                    nextMove()
                } else {
                    print("checkmate")
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...