Я использую 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
}
}
}
Вы могу заставляете отображение немедленно (вызывая 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")
}
}
}
}
}