Автокликер Clickermann :: Форум
Основной раздел => Предложения => Topic started by: Vint on January 10, 2013, 03:22:59 PM
-
Какой есть способ правильно экстренно выбраться из кучи вложенных циклов/подпрограмм глобально ну хотя бы в «корень» скрипта?
Какие можно придумать способы? Мне пока в голову пришло только рекурсивно вызывать скрипт LOAD("скрипт.cms"). Можно ли так делать? Или это тот же досрочный выход из цикла? Я понимаю, что переменные сохраняются, а вот сбрасывается там стэк или как всё там реализовано не знаю. С программированием не знаком. В далёкие времена, для себя писал программки на ассемблере для Z80. Так там RET как раз был выход из подпрограммы. И выходов могло быть много (привет Оравэну). RET снимала с вершины стэка адрес возврата из подпрограммы. Можно было хитрым макаром, следя за стэком выскочить куда угодно из любого числа подпрограмм или вообще в любое место не нарушая работы.
Чёт я отвлёкся...
Зачем это нужно? Всегда хочется правильной, если нужно длительной и бесперебойной работы скрипта. Речь сейчас не об ошибках в скрипте (представим, что ошибок нет), а о согласовании работы скрипта и целевого приложения. Для универсальности и исключения влияния нестабильной скорости интернет соединения, параллельно работающих программ и т.д., я если необходимо ожидать реакцию целевого приложения (например игры), в большинстве мест использую цикл ожидания с проверкой пиксела/картинки/суммы и т.п.
Типа такого:
$fon = 1
WHILE($fon = 1)
GETSCREEN
IF (PXL($lx+60, $ly-137)=6643283)
$fon = 0 // выходим из цикла fon
END_IF
WAITMS(100)
END_CYC
Так вот, если с целевой программой что-то пошло не так (не отработал клик или вылезло незапланированное окно), то всё из цикла мы уже не вылазим.
Сейчас я конечно использую внутри подобного цикла проверку на время ожидания или количество циклов. Выход правда получается сильно запутанным даже при двух вложениях, а если больше, наступает Амба с растущим числом проверок и перескоков GOTO к концу циклов/подпрограмм. Короче чёрт ногу сломит если делать всё по правильному.
Если можно использовать LOAD самой себя из под кучи вложенных циклов то это хоть какой-то выход.
Пример:
#name "Рекурсия"
IF($reboot > 0)
// здесь проводится обработка ошибок если нужно и разная реакция с раздачей слонов
// перезагружаем страницу/перезапускаем приложение, топаем по метке внутрь скрипта и т.д.
//...
$reboot = 0
END_IF
// основная программа
//...
WHILE(условие1)
WHILE(условие2)
// и т.д.
GOSUB(proverka) // проводим проверку на зависание/сбой
END_CYC
END_CYC
//...
//--------------------------------
SUB (proverka)
IF(условие)
$reboot = 1
LOAD("Опыты\Рекурсия.cms")
END_IF
END_SUB
//--------------------------------
Если так нельзя, как можно? Может сделать хотя бы какой нибудь RESET который будет перезапускать скрипт с очисткой переменных и всяких входов в циклы. Короче то же что и стоп/пуск.
Если кого запутал - простите :)
-
RESET я уже предлагал но пока что то не двигается дело.
Как вариант используй выход на начало скрипта по ГОТО. Хоть там и написано что будет ошибка он ошибок не наблюдается.
start:
GOSUB(sub_name)
print("После суба")
HALT
SUB(sub_name)
print("Я в субе")
WAITMS(100)
GOTO(start)
END_SUB
-
Нет, сразу то ничего не наблюдается. Но я думаю есть что-то в виде стэка. И если не выйти из последнего, из преведущего уже не вернуться. Но это в моём применении не важно. Опасаюсь при длительной работе скрипта он может жрать память или пойти вразнос. Хотелось бы конкретики, чем чревато?
-
Винт, привет!
Суть вопроса ясна. При любой реакции приложения скрипт должен работать.
Я для этого использую такую схему.
Здача: Н
Этапы выполнения: 1, 2, 3, 4...№, 0.
То есть любая задача по плечу кликеру путём выполнения последовательности простых действий.
Каждый этап выполнения, далее блок, имеет одну и туже структуру. Блок 0 используется для завершения цикла выполнения задачи, т.е. обнуляет переменные и проверяет, чтобы всё закончилось как надо.
SUB ( Block# )
// описание блока
// == // объвление переменных
// == // проверка входящих данных
// == // действия блока
// == // проверка результата действия блока
// == // проверка завершения блока и переход к следующему
end_sub
Структура настолько проста, что кажется всё понятно. Если нет - обсудим.
Следует отметить, что в последней части блока "переход к следующему" происходит в зависимости от результата действий и\или входящих данных. То есть ключ к универсальности скрипта - проверки и гибкая система переходов между блоками(этапами выполнения задачи).
При этом такая структура снимает нужду в использовании GOTO.
-
Всему этому делу сильно бы помогло наличие функций.
-
Ну вот простой пример проверки истекшего времени задержки.
Как тут можно обойтись без goto?
$time29 = $_time_t + 180
wwwar9:
If( $time29 < $_time_t )
LCLICK(897,178) // закрыть окно
waitms(rnd(150,250))
LCLICK(897,178) // закрыть окно
waitms(rnd(2250,2350))
goto(wwwar12)
end_if
И ещё непонятно , для чего обнулять переменные, если можно перед новым блоком настряпать новых и присвоить им нули через DEFINE ?
-
используй выход на начало скрипта по ГОТО. Хоть там и написано что будет ошибка он ошибок не наблюдается.
В этом случае таки идут ошибки , но как-то странновато.
То есть, то нет.
Помогает иногда сохранить скрипт, выйти из программы и снова его запустить.
А на лету по "применить" часто не пашет.
-
2 ЦИТРИН
Не совсем понятен приведенный Вами код - что то с метками там... А еще можно цикл WHILE попробовать использовать, можно добавлять переменные для указания статуса... Вариантов много. На самом деле все зависит от конкретной задачи. Можно делать и без ГОТО :)
-
не можно, а нужно.
Нет, сразу то ничего не наблюдается. Но я думаю есть что-то в виде стэка. И если не выйти из последнего, из преведущего уже не вернуться.
this. если выпрыгивать через goto из цикла или саба то в стэке будут накапливаться точки возврата, которые в нормальном режиме работы удаляются из стэка при завершении цикла\саба. помимо неминуемой утечки памяти, в ряде случаев это приведет к сбоям в логике
самый оптимальный вариант для цикла - выход через флаг