Я создал простую игру в крестики-нолики, и у меня есть несколько ботов, с которыми вы можете играть. Я пытаюсь сделать задержку между последовательными ходами ботов, иначе все последовательные движения ботов появятся на экране одновременно.
вот что я пробовал в своем коде:
// bot functionality
private fun botTurn(botDifficulty: Int) {
var botMove = 100
when (botDifficulty) {
1 -> botMove = easyBot(confirmedMoves)
2 -> botMove = mediumBot(activePlayer, confirmedMoves, maxPlayers)
3 -> botMove = hardBot(activePlayer, confirmedMoves, maxPlayers)
else -> Toast.makeText(this, "What sort of bot is this??", Toast.LENGTH_SHORT).show()
}
trueCellID = botMove
// colour chosen segment
setSegmentColor(trueCellID, -1, activePlayer)
// TODO add 1-2 second delay after confirming move?
Log.d("Wait", "start of wait $activePlayer")
Thread.sleep(1000)
Log.d("Wait", "end of wait $activePlayer")
confirmMove()
}
использование Thread.sleep, похоже, просто задерживает все обновления пользовательского интерфейса до тех пор, пока не произойдет все сны botPlayer. Я также пытался использовать Handler.postDelayed
, GlobalScope.launch
с блоком delay
и runOnUiThread
с SystemClock.sleep(1000)
- у них та же проблема: выполнение всего ожидания бота, а затем обновление пользовательского интерфейса.
Я даже попытался адаптировать это решение, чтобы попробовать - как дождаться Android runOnUiThread должен быть закончен? но получил тот же результат - большая задержка, чем все обновления пользовательского интерфейса.
Есть ли решение для этого или я пропустил что-то простое?
Int
для уровня бота вам не пришлось бы иметь дело с дополнительной веткойwhen
(если это не имеет смысла в вашем коде). Кроме того, вместо выражения можно использоватьwhen
:val botMove = when(botDifficulty) {...}
- person Joffrey   schedule 25.05.2021botTurn
? Вы вызываете его последовательно для каждого бота? Или вы используете сопрограммы для их параллельного вызова? - person Joffrey   schedule 25.05.2021confirmMove()
увеличиваетactivePlayer
, а затем проверяет, является ли активный игрок ботом или человеком. если это бот, то вызываетсяbotTurn
. - person KinectDeveloper23   schedule 25.05.2021confrimMove()
вызываетbotTurn()
и наоборот? Это не очень хорошая идея ;-) Было бы намного чище, если быbotTurn()
выполнял решение/движение только ботом, а другой код определял бы ход бота или человека, вызывал быbotTurn()
и ждал между ходами. - person broot   schedule 25.05.2021Handler.postDelayed()
, иGlobalScope.launch()
должны сработать, так что я думаю, вы сделали что-то не так. Например, вы можете сделатьbotTurn()
приостанавливаемым, вызвать его внутриGlobalScope.laucnh()
и заменитьThread.sleep()
наdelay()
— это должно работать без блокировки пользовательского интерфейса. - person broot   schedule 25.05.2021Handler.postDelayed()
. Ничто не блокирует пользовательский интерфейс — повороты ботов действительно слишком быстрые, они появляются мгновенно, когда это делают не люди. У меня есть функцияwaitYourTurn()
, которая проверяет, чья сейчас очередь, и если это бот, если это бот, тоbotTurn()
— это должно заполнить сегмент (пользовательский интерфейс), затемconfirmMove()
— это сохраняет ход и увеличиваетactivePlayer
и снова вызываетwaitYourTurn()
. - person KinectDeveloper23   schedule 25.05.2021botTurn()
->confirmMove()
->checkForWinner()
->waitForBots()
->botTurn()
, так что с каждым поворотом вы все глубже и глубже погружаетесь в стек вызовов. Думаю, у вас нет проблем только потому, что в крестиках-ноликах очень ограниченное количество ходов. - person broot   schedule 25.05.2021postDelayed()
(закомментировано в коде), но на этот раз поместитеsetSegmentColor()
иconfirmMove()
в блокpostDelayed()
. Но это полностью изменит поток кода, так что вы можете столкнуться с сбоями или другими ошибками. - person broot   schedule 25.05.2021postDelayed()
сработало отлично! спасибо - никаких других сбоев или ошибок, что всегда приятно! Если вы хотите официально ответить, я подтвержу это, в противном случае я отложу ваш ответ в конце дня, еще раз спасибо - person KinectDeveloper23   schedule 26.05.2021