Что нового

Ошибка: Recursion level has been exceeded

Fazer

Новичок
Сообщения
2
Репутация
0
Подскажите в чём проблема.

Одновременно на компе работает 5 скриптов, все они взаимосвязаны и управляют друг другом, если нужно то отключают или включают друг друга. С ними вопросов нет, работают без сбоев и ошибок.
Понадобилось добавить ещё один скрипт, теперь после 1-2 часов работы этот скрипт выдаёт ошибку: Recursion level has been exceeded, и скрипт терминейтится. Остальные как работали так и работают.

Вот сам скрипт:

Код:
Func SaveMode()
	PixelSearch(850, 445, 1000, 585, 0xFF0000, 10); check f11
		If @error = 0 then
			Send("{F11}", 0)
		EndIf
	Sleep(1000)
	
	PixelSearch(512, 636, 517, 640, 0xD71919, 30); check armor status
		If @error = 0 then
			Send("{F7}", 0)
			Send("{F8}", 0)
			Send("{F9}", 0)
			WinKill("EVE")
		EndIf
	Sleep(1000)

SaveMode()

EndFunc


Ошибку выбивает на первой строчке скрипта:
Код:
PixelSearch(850, 445, 1000, 585, 0xFF0000, 10); check f11
 

killbond

Осваивающий
Сообщения
96
Репутация
32
Re: Выбивает ошибку

У тебя здесь рекурсия - функция выполняет некоторые действия и вызывает саму же себя без всяких параметров, без всяких на то условий (т.е. выполняться это будет вечно) - это не есть хорошо! (Поэтому ругается интерпретатор) Лучше поставь эту функцию в цикл:
Код:
Func SaveMode()
	Local $fToggle = true
	While $fToggle
		PixelSearch(850, 445, 1000, 585, 0xFF0000, 10); check f11
		  If @error = 0 then
			 Send("{F11}", 0)
		  EndIf
		Sleep(1000)

		PixelSearch(512, 636, 517, 640, 0xD71919, 30); check armor status
		  If @error = 0 then
			 Send("{F7}", 0)
			 Send("{F8}", 0)
			 Send("{F9}", 0)
			 WinKill("EVE")
			 $fToggle = Not $fToggle
		  EndIf
		Sleep(1000)
	Wend
EndFunc

Не проверял, но должно работать, если место, где ты убиваешь окно Евы является логическим концом функции.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: Выбивает ошибку

Fazer
Предупреждение
1. переименуй тему так, чтобы было понятно о чем речь без необходимости заглядывать внутрь.
2. обрамляй код тэгами [code][/code] или [autoit][/autoit]
 
Автор
F

Fazer

Новичок
Сообщения
2
Репутация
0
Re: Выбивает ошибку

спс, проверил, всё работает как и должно.
Сейчас запущу на долгую проверку.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
OffTopic:
Темку бы перенести :whistle:

а если по теме, то ты вызываешь из функции ее саму же. это чрезвычайно полезный маневр, но имеет свой спектр применений. и соответственно ряд ограничений. к примеру ограниченное кол-во уровней вложенности (другими словами вызов себя из себя же). поэтому применять ее надо тогда, когда точно знаешь, что этот предел не будет превышен. например, поиск файлов в папке и ее подкаталогов. с большой долей вероятности можно сказать, кол-во вложенных подкаталогов в данный не превысит 5100
 

Notum

Новичок
Сообщения
71
Репутация
0
Всем доброго дня!

Имеется схожая проблема с автором данной темы - тоже имеется бот, и тоже состоит из кучи логических функций. Попытаюсь рассказать по подробнее - имеется игровой бот, написанный на AutoIt, который в свою очередь состоит из кучи логический фунций, и они периодически вызывают либо сами себя, если нужного события не произошло, либо другие логические функции, если событие произошло. Логический конец в данном схеме имеется, но он бывает крайне редко - бот хорошо написал! ;D Но всё же - есть один неприятный момент - бот работает примерно 7200 секунд, а потом вылетает с ошибкой Recursion level has been exceeded. Бот достаточно большой и выкладывание его сюда - наврятли чем то поможет, по этому прошу поделиться советом -

По какому принцыпу и в каком месте надо вставлять функции в цикл?

Заранее благодарен за дельный совет.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Тема вообще не по разделу, ей самое место в "Автоит для новичков".
Notum, даже не видя кода твоего бота, могу сказать что он наикорявейший. Чтобы не было рекурсии используйте возвраты
 

Notum

Новичок
Сообщения
71
Репутация
0
Belfigor сказал(а):
Тема вообще не по разделу, ей самое место в "Автоит для новичков".
Notum, даже не видя кода твоего бота, могу сказать что он наикорявейший. Чтобы не было рекурсии используйте возвраты

Уважаемый, Belfigor
Как вы наверное успели заметить - тему создавал не я, и дабы не плодить "темы-повторы" решил написать здесь.
По существу - если не сложно - не могли бы вы, слегка по подробнее описать/рассказать по теме - возвратов? Что это из себя представляет? Как данное решение поможет мне в сложившийся ситуации?

Заранее спасибо.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Notum сказал(а):
Всем доброго дня!

Имеется схожая проблема с автором данной темы - тоже имеется бот, и тоже состоит из кучи логических функций. Попытаюсь рассказать по подробнее - имеется игровой бот, написанный на AutoIt, который в свою очередь состоит из кучи логический фунций, и они периодически вызывают либо сами себя, если нужного события не произошло, либо другие логические функции, если событие произошло. Логический конец в данном схеме имеется, но он бывает крайне редко - бот хорошо написал! ;D Но всё же - есть один неприятный момент - бот работает примерно 7200 секунд, а потом вылетает с ошибкой Recursion level has been exceeded. Бот достаточно большой и выкладывание его сюда - наврятли чем то поможет, по этому прошу поделиться советом -

По какому принцыпу и в каком месте надо вставлять функции в цикл?

Заранее благодарен за дельный совет.

В твоем случае (я думаю) никакая функция не должна вызывать саму себя. Рекурсия нужна в ряде специфических задач (например поиск файла на диске), но в ботах уж точно никчему.
 

Notum

Новичок
Сообщения
71
Репутация
0
Yashied сказал(а):
Notum сказал(а):
Всем доброго дня!

Имеется схожая проблема с автором данной темы - тоже имеется бот, и тоже состоит из кучи логических функций. Попытаюсь рассказать по подробнее - имеется игровой бот, написанный на AutoIt, который в свою очередь состоит из кучи логический фунций, и они периодически вызывают либо сами себя, если нужного события не произошло, либо другие логические функции, если событие произошло. Логический конец в данном схеме имеется, но он бывает крайне редко - бот хорошо написал! ;D Но всё же - есть один неприятный момент - бот работает примерно 7200 секунд, а потом вылетает с ошибкой Recursion level has been exceeded. Бот достаточно большой и выкладывание его сюда - наврятли чем то поможет, по этому прошу поделиться советом -

По какому принцыпу и в каком месте надо вставлять функции в цикл?

Заранее благодарен за дельный совет.

В твоем случае (я думаю) никакая функция не должна вызывать саму себя. Рекурсия нужна в ряде специфических задач (например поиск файла на диске), но в ботах уж точно никчему.

Каким же образом реализовать следующее:

Func ColorSearch()
SearchPixel(****)
If True Then
OtherFunc()
Else
Color Search()
EndIf

?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Код:
While 1
   SearchPixel(****)
   If True Then
      OtherFunc()
   Else
      AnotherFunc()
   EndIf
   Sleep(100)
WEnd
 

Notum

Новичок
Сообщения
71
Репутация
0
Огромное спасибо, принцип вроде понял. Пойду тестить...
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
OffTopic:
Только я вот не понял, разве это баг? Почему тема не в разделе для новичков? ;D
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Notum
ну это же твоя функция. я не знаю из чего она состоит ;D
 

Belfigor

Модератор
Локальный модератор
Сообщения
3,608
Репутация
941
Код:
Case $ToCheck = "Cargo Hold"
            If ConCheck("Location") = "Идет загрузка..." Then Return "Cargo Hold - Идет загрузка..." 
            #cs - Обратиться сюда командой ConCheck("Cargo Hold") - если мы хотим различить заполненность трюма по одному из трех состояний Full, Empty, Not Empty
            #ce - Обратиться сюда командой ConCheck("Cargo Hold", "%") - если мы хотим узнать процентное значение заполненности трюма 0-100%
            Local $CargoBarStatus = PixelSearch($CargoBar[0], $CargoBar[1], $CargoBar[2], $CargoBar[3], $CargoBar[4], $CargoBar[5]) ;Проверяем есть ли чо в трюме
            If @error Then ;Цвет не нашли - значит трюм заполнен на 100% (Верно лишь тогда когда окно трюма находится на правильной позиции) (При необходимости надо прикрутить проверку наличия окна, и возврат его текущих координат или же возврат окна на эталонные координаты)
                If $AdvCheck = "%" Then Return 100&"%" ;Если $AdvCheck = "%" (Запрос был сформирован как ConCheck("Cargo Hold", "%") вернуть 100%
                Return "Full" ;Вернуть Full
            Else ;Если трюм не полный
                If $CargoBarStatus[0] = $CargoBar[0]+1 Then ;Если трюм пустой
                    If $AdvCheck = String("%") Then Return 0&"%" ;Вернуть 0%
                    Return "Empty" ;Если $AdvCheck <> "%" - Вернуть Empty
                Else ;Финальная проверка если трюм не пустой и не полный. Вернуть текущее процентное значение состояния заполненности трюма. Расчет идет по формуле: Округлить результат((([Координата места где заканчивается индикатор заполненности] - [Координата правого края области поиска] * 100 / 99), 0) P.S. 99 - Ширина области поиска
                    If $AdvCheck = "%" Then Return Round((($CargoBarStatus[0] - $CargoBar[0]) * 100 / 99), 0)&"%" ;Если $AdvCheck = "%" (Запрос был сформирован как ConCheck("Cargo Hold", "%") - расчитать текущее % значение заполненности трюма и вернуть его в формате [Число]%
                    Return "Not Empty" ;Вернуть что трюм НЕ пустой
                EndIf
            EndIf

вот пример, если ты именно это хотел увидеть
 

Notum

Новичок
Сообщения
71
Репутация
0
Огромное спасибо!


Добавлено:
Сообщение автоматически объединено:

Notum сказал(а):
Kaster сказал(а):
Код:
While 1
   SearchPixel(****)
   If True Then
      OtherFunc()
   Else
      AnotherFunc()
   EndIf
   Sleep(100)
WEnd

Ув.Kaster, как я понял OtherFunc() тоже должна состоять из While, правильно?

Мне всё же не понятно, как в вашем примере реализована повторная проверка на цвет в нужной точке? Я хочу сказать, что... Если цвет не найден, то надо ждать 200 и заново искать в той же точке.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Notum [?]
Если цвет не найден, то надо ждать 200 и заново искать в той же точке
тогда так
Код:
While 1
   SearchPixel(****)
   If True Then OtherFunc()
   Sleep(100)
WEnd
 

Notum

Новичок
Сообщения
71
Репутация
0
Принцип понял, но реализовать в своём скрипте не получается... :'(
Если не сложно - посмотрите пожалуйста мой скрипт и ткните носом - что тут не так?

При нажатии кнопки в GUI идёт вызов функции FindEnemy()

Код:
Func FindEnemy() ;функция поиска противника
if $x = 60 Then ; то есть если мы сделали проверку на цвет 60 раз, то что то не так и есть смысл сделать REFRESH
	Send("{F5}")
Else
EndIf	


While $x < 60
	$coord = PixelSearch( 80, 174, 975, 690, 0xFFF5E7, 3, 1)
		If Not @error Then
			MouseMove($coord[0], $coord[1], 0) ;координаты моба
			Sleep(200)
			MouseClick("left")
			Sleep(200)
			CheckFight()
		Else
			$x = $x + 1
			Sleep(300)
			FindEnemy()
	EndIf
WEnd
;Если мы дошли до сюдава, то значит - моба нет, а значит - есть смысл подождать
Sleep(10000)
;MsgBox(0, "Количество попыток", $x)
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Код:
Func _FindEnemy()
	While 1
		$coord = PixelSearch( 80, 174, 975, 690, 0xFFF5E7, 3, 1)
		If Not @error Then
			MouseMove($coord[0], $coord[1], 0) ;координаты моба
			Sleep(200)
			MouseClick("left")
			Sleep(200)
			CheckFight()
		Else
			$x = $x + 1
			Sleep(300)
			If $x = 60 Then Send("{F5}")
		EndIf
	WEnd
EndFunc
 
Верх