Что нового

функция вызывающая саму себя.

yaodnako

Продвинутый
Сообщения
120
Репутация
78
Код:
Func Mine();включить лазеры для добычи если дистанция ближе 10км
	Do
		Sleep (100)
		SelItemCheck();проверка на выбор объекта(selected item).
		ToolTip("Подлетаю к метеору ближе 10 км",0,0)
	Until DistanceCheck()=1;повторяем цикл,пока дистанция не станет ближе 10км
	MouseClick ("left",880, 74);жмем кнопку лока цели
	ToolTip("Лочу цель",0,0)
	Sleep (4000);ждем окончания лока


	While CargoCheck()=0;проверка на заполненность трюма
		LockCheck()
		ToolTip("Атаке!",0,0)
		Send ("{ENTER}")
		CargoCheckOpt()
	Send ("{f1}")
	Send ("{f2}")
	LockCheck()
	$stripwork=random (39000,41000)
	Sleep ($stripwork)
	LockCheck();проверка на потерю лока астероида
	Send ("{ENTER}")
	Send ("{f1}")
	Send ("{f2}")
	Sleep (2000)
	Send ("{ENTER}")
	ToolTip ("ждем пока не заполнится трюм",0,0)
	WEnd
EndFunc

Func LockCheck();проверка цели на лок
	PixelSearch(635, 81,635, 81,0x404040)
	If not @error Then
		Sleep(500)
		ToolTip ("Лок не сбился",0,0)
	Else
		ToolTip("Сбился лок",0,0)
		Sleep (500)
		ToolTip("начинаю поиск ближайшего метеора",0,0)
		Sleep (1000)
		mine();если лок сбился начинаем процедуру лока и бурения,как будто только прилетели на белт.
	EndIf
EndFunc


вот есть кусок скрипта.есть функция LockCheck() внутри нее может вызваться снова вся функция целиком mine().
вопрос - если вызвался mine() то запоминается ли то место из которого была вызвана функция? или скрипт забывает его и просто начинает эту функцию заного?
Есть ли функция для того,чтобы забывалось это место если он запоминает его?

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

Или даже не так.представьте есть :
1.функция 1
2.функция 2
3.функция mine()
4.функция 4.

и если внутри mine() снова вызовется майн - то предидущий mine() не завершится пока не завершиться нововызванный?т.е. функция 4 так и не вызовется?
 

FlatX007

Tattoo!
Сообщения
197
Репутация
35
Незнаю может я не так понял

Код:
Global $Func_Mine
Const $LOCKCHECK = "LOCKCHECK"

Func Mine($Opt = 0);включить лазеры для добычи если дистанция ближе 10км

	 $Func_Mine = $Opt

	If $Func_Mine = $LOCKCHECK Then
		MsgBox(0, "", "Функция Mine() запустилась из функции LockCheck()")
	ElseIf

    Do
        Sleep (100)
        SelItemCheck();проверка на выбор объекта(selected item).
        ToolTip("Подлетаю к метеору ближе 10 км",0,0)
    Until DistanceCheck()=1;повторяем цикл,пока дистанция не станет ближе 10км
    MouseClick ("left",880, 74);жмем кнопку лока цели
    ToolTip("Лочу цель",0,0)
    Sleep (4000);ждем окончания лока


    While CargoCheck()=0;проверка на заполненность трюма
        LockCheck()
        ToolTip("Атаке!",0,0)
        Send ("{ENTER}")
        CargoCheckOpt()
    Send ("{f1}")
    Send ("{f2}")
    LockCheck()
    $stripwork=random (39000,41000)
    Sleep ($stripwork)
    LockCheck();проверка на потерю лока астероида
    Send ("{ENTER}")
    Send ("{f1}")
    Send ("{f2}")
    Sleep (2000)
    Send ("{ENTER}")
    ToolTip ("ждем пока не заполнится трюм",0,0)
    WEnd
EndFunc

Func LockCheck();проверка цели на лок
    PixelSearch(635, 81,635, 81,0x404040)
    If not @error Then
        Sleep(500)
        ToolTip ("Лок не сбился",0,0)
    Else
        ToolTip("Сбился лок",0,0)
        Sleep (500)
        ToolTip("начинаю поиск ближайшего метеора",0,0)
        Sleep (1000)
        Mine($LOCKCHECK);если лок сбился начинаем процедуру лока и бурения,как будто только прилетели на белт.
    EndIf
EndFunc
 

SyDr

Сидра
Сообщения
651
Репутация
158
yaodnako
Запомни, как написал, так и будет работать.
Есть функция. Работает. Вызывает другую функцию. Эта функция тоже что-то делает, а потом вызывает первую. Неправильно. Рекурсия для этого не предназначена.

Для выхода из функции можно использовать Return
 
Автор
yaodnako

yaodnako

Продвинутый
Сообщения
120
Репутация
78
I) ок.все равно мне непонятно что происходит с предидущей функцией.
1.запускается mine()
2.из LockCheck() снова запускается mine(),но преидущий mine() еще не завершился.а если внутри 2го mine(),запустится еще один mine().это значит,что 2 функции не до конца завершенные mine() ,буду ждать завершения текущей и затем по порядку завершаться.пока не дойдет до самой первой запущенной функции.правильно я понял? т.е. завершения первой не будет если завершиться только 3я.только после завершения 3й,2й и самой себя она завершиться?

II)а для чего предназначена рекурсия?

III)как сделать так,чтобы при вызове из функции LockCheck() функции Mine() и ее завершении - завершилась все функции mine() до этого.или может как по другому сделать.

p.s.спасибо всем за помощь...
 

SyDr

Сидра
Сообщения
651
Репутация
158
Рекурсия предназначена для упрощения решения многих задач. Смысл в том, что задача разбивается на подзадачи, которые в свою очередь, также разбиваются на элементарные и т.д. Решение самой простой задачи обычно тривиально. Пример, факториал числа:

Код:
Func Fact($n) ;обычный цикл
Local $res = 1
Local $i
For $i = 1 To $n
$res *= $i
Next
Return $Res
EndFunc

Func FactRect($n) ;рекурсия
If $n = 1 Then
Return 1
Else
Return $n * FactRect($n-1)
EndFunc

Но вообще, это один из самых страшных примеров. Здесь рекурсия совсем не нужна.

А в твоём случае лучше всего-делать примерно так:
Код:
While 1
If <трюм полон> Then <выход из цикла или программы>
<подлететь к астероиду и начать делать тёмные дела>
While <Цель залочена и трюм не полон>
<Ничего не делать :)>
WEnd
WEnd
 

Feldsherus

Новичок
Сообщения
2
Репутация
0
На самом деле при рекурсии функция помнит, где она вызвала сама себя, и ничего плохого не произойдет, будет работать примерно, как вложенный цикл
 

SyDr

Сидра
Сообщения
651
Репутация
158
Ну да. Преимущество рекурсии в простоте записи. Но если в самой функции используется большие локальные массивы данных, то рекурсия может всё погубить. К тому, в AutoIt есть ограничение на число рекурсивных вызовов.
 
Автор
yaodnako

yaodnako

Продвинутый
Сообщения
120
Репутация
78
всем огромное спасибо - достаточно было ,чтобы приперло сделать и решение нашлось за 5-10 минут.

Код:
Func Mine();включить лазеры для добычи если дистанция ближе 10км
	Minestage1()

While CargoCheck()=0;проверка на залоненность трюма
	While LockCheck()=1;проверка на лок.
	ToolTip("Атаке!",0,0)
	Send ("{ENTER}")
	Send ("{f1}")
	Send ("{f2}")
	$stripwork=random (39000,41000)
	Sleep ($stripwork)
	Send ("{ENTER}")
	Send ("{f1}")
	Send ("{f2}")
	Sleep (2000)
	Send ("{ENTER}")
	ToolTip ("ждем пока не заполнится трюм",0,0)
	If CargoCheck()=1 Then
		ExitLoop;проверка на заполненность трюма,чтобы выйти из цикла бурения.
	EndIf
	WEnd
WEnd
EndFunc
 
Верх