Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Częste wywoływanie tej samej funkcji problem.


Tieru

Rekomendowane odpowiedzi

Opublikowano

Witam, 

Po napisaniu poprawnie całego bota, który wywoływuje ciągle funkcje i przechodzi do kolejnych, program tak działa i się zapętlił bez While,do,for etc. działa za pomocą funkcji.

Tylko teraz jest problem, ImageSearch albo AutoIT widocznie nie lubi tego i po drugim "okrążeniu" program wywala z błędem w konsoli

>"D:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "C:\Users\Tieru\Desktop\AutoIT\no.au3"    
"D:\Program Files (x86)\AutoIt3\Include\ImageSearch.au3" (31) : ==> Recursion level has been exceeded - AutoIt will quit to prevent stack overflow.:
return _ImageSearchArea($findImage,$resultPosition,0,0,@DesktopWidth,@DesktopHeight,$x,$y,$tolerance)
 
>Exit code: 1    Time: 117.9
 

Przykład w moim bocie 

Func wstaw_narzedzia_tTRZECIATAK()
  global $y = 0, $x = 0
  Local $search = _ImageSearch('T.bmp', 1, $x, $y, 0)
  Sleep ( 500 )
If $search = 1 Then
  MouseClick( "PRIMARY", $x, $y )
  Sleep ( 100 )
  MouseClick( "PRIMARY", 644, 436 )
  Sleep ( 500 )
  Send("12")
  MouseClick( "PRIMARY", 809, 475 )
  Sleep ( 500 )
  wstaw_narzedzia_dTRZECIATAK()
Else
  MsgBox( 1, "BRAK NARZEDZI", "Nie znalazłem t!" )
EndIf
EndFunc
 

Func  wstaw_narzedzia_dTRZECIATAK()
  global $y = 0, $x = 0
  Local $search = _ImageSearch('D.bmp', 1, $x, $y, 0)
  Sleep ( 500 )
If $search = 1 Then
  MouseClick( "PRIMARY", $x, $y )
  Sleep ( 100 )
  MouseClick( "PRIMARY", 644, 436 )
  Sleep ( 500 )
  Send("12")
  MouseClick( "PRIMARY", 809, 475 )
  Sleep ( 500 )
  atakuj_TRZECIATAK()
Else
  MsgBox( 1, "BRAK NARZEDZI", "Nie znalazłem d!" )
EndIf
EndFunc

 

Proszę o pomoc, na innych forach wyczytałem 

"Your problem is recursion. Recursion simply means that a function calls itself again and again. But there must be a break condition, else your function will call itself endlessly. For example:

 

Global $counter = 0
Recursion()
 
Func Recursion()
$counter += 1
ConsoleWrite($counter & @CRLF)
Recursion()
EndFunc  
A correct use of recursion would be for example:

Global $counter = 0
Recursion()

Func Recursion()
$counter += 1
If $counter >= 10 Then Return
ConsoleWrite($counter & @CRLF)
Recursion()
EndFunc  
Na innym forum już proponują pętle:

Recursion is not a cool technique. Why not try looping?

 

AutoIT will stop because "Recursion level has been exceeded - AutoIt will quit to prevent stack overflow." after about 3,898 recurrences consistently. The problem is I want to run this for 10,000-100,000 times.

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Opublikowano

No dobrze, a Twoje pytanie to? Opisałeś co masz, co wyczytałeś, ale nie zadałeś konkretnego pytania.

Chciałbym uniknąć tego błędu, czy muszę przerobić kod 1000 linijek na pętle czy da się to załatwić w funkcjach jak u mnie jest?

Funkcje mi odpowiadają, bo jest duża swoboda i mogę w każdej chwili działać od środka kodu, a w pętli wydaje mi się więcej kłopotu. :<

 

Nie wiem, muszę wstawić w każdej funkcji Return czy co?

Tworzę w tym zaledwie kilka dni, bardzo mi to forum pomaga, a nie mam czasu by uczyć się całego autoit'a jak tworzyć nie wiadomo jakie algorytmy.

Uczę się na tym jak tutaj mi pomagacie.

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Opublikowano

Możesz w else spróbować dodać return, pewny nie jestem, a nie mam jak teraz tego sprawdzić. Z przykładu "dobrej" rekurencji wynika, że taki zabieg powinien pomóc.

 

@Edit

Kwestią jest czy imagesearch nie trawi tylko złej rekurencji czy całkowicie jej nie akceptuje. Wtedy spróbuj wrzucić pętle w funkcji.

Opublikowano

Możesz w else spróbować dodać return, pewny nie jestem, a nie mam jak teraz tego sprawdzić. Z przykładu "dobrej" rekurencji wynika, że taki zabieg powinien pomóc.

 

@Edit

Kwestią jest czy imagesearch nie trawi tylko złej rekurencji czy całkowicie jej nie akceptuje. Wtedy spróbuj wrzucić pętle w funkcji.

Niestety dalej to samo (wysłałem Ci cały kod programu na PW)

edit - sorka, że code nie dałem

 

Return mi wyłączy program, a ma program działać,

pierwszy raz program zadziała do końca, potem działa od nowa ale przy ataku pierwszym program wyrzuca mi błąd przekroczenia resurcion... :/ 

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Opublikowano

Czemu zamiast rekurencji nie użyjesz pętli while w środku funkcji? Nie będziesz musiał zmieniać w parunastu miejscach niczego.

Opublikowano

Czemu zamiast rekurencji nie użyjesz pętli while w środku funkcji? Nie będziesz musiał zmieniać w parunastu miejscach niczego.

Na przykład w takich miejscach, gdzie wraca i zapełnia rekurencje?

Func PaliSie1

If ...

...

Else

PaliSie1()

EndFunc

 Func PaliSie4()
       global $y = 0, $x = 0
  Local $search = _ImageSearch('PALISIE.bmp', 10, $x, $y, 0)
  Sleep ( 15 )
If $search = 1 Then
  MouseClick( "PRIMARY", $x, $y )
  Sleep ( 100 )
  MouseClick( "PRIMARY", 770, 422 )
  Sleep ( 100 )
  MouseClick( "PRIMARY", 830, 377 )
  Sleep ( 100 )
  MouseClick( "PRIMARY", 849, 421 )
  Sleep ( 100 )
  MouseClick( "PRIMARY", 905, 245 )
  Sleep ( 60000 )
  wybierz_oboz1() ;cale od nowa
  Else
  PaliSie4()
  Return
EndIf
 EndFunc
Ogólnie najwygodniej bym dał na całe działanie bota pętlę While 1, lecz wywala mi błąd od razu przy pierwszej funkcji w takich przypadkach. :(

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Opublikowano

Z tego co widzę błędu nie powoduje sama funkcja tylko program który ją wywołuje, tworzy i nazywa ciągle jedną i tą samą funkcję. 

Jak użyje pętli w środku funkcji zwłaszcza z jedynką to może wywalić mu czasami albo praktycznie cały czas stack overflow. Nie wyjdzie z funkcji do czasu aż ją zakończy czy przełączy inna funkcja. 

 

Zamiast while można użyć until do zrobienia  pętli .

 

Tak przy okazji , bez sensowne jest ciągłe ładowanie i sprawdzanie obrazka skoro przypisujesz mu już zmienną, wywal to $search na sam początek skryptu. Wystarczy jak raz użyje skoro się nie zmienia. 

 

Nie przypisuj tej samej zmiennej dla rożnych obrazków zwłaszcza że używasz LOCAL ! Ponumeruj sobie dla różnych plików $search1 dla t, $search2 dla d... itd   , to samo zrób ze zmiennymi jaki zwraca program , inne dla pierwszego wyniku , inne dla drugiego np x,y ( pierwszy ) a,b (drugi) itd 

 

Co do tego RETURN to zwróci tylko wynik działania funkcji czyli kod błędu albo np koordynaty, tutaj return nie służy do cofania tylko zwracania wartości/wyniku w momencie użycia. 

Mózg to nie mydło; nie ubędzie Ci go, gdy go użyjesz.

Opublikowano

Z tego co widzę błędu nie powoduje sama funkcja tylko program który ją wywołuje, tworzy i nazywa ciągle jedną i tą samą funkcję. 

Jak użyje pętli w środku funkcji zwłaszcza z jedynką to może wywalić mu czasami albo praktycznie cały czas stack overflow. Nie wyjdzie z funkcji do czasu aż ją zakończy czy przełączy inna funkcja. 

 

Zamiast while można użyć until do zrobienia  pętli .

 

Tak przy okazji , bez sensowne jest ciągłe ładowanie i sprawdzanie obrazka skoro przypisujesz mu już zmienną, wywal to $search na sam początek skryptu. Wystarczy jak raz użyje skoro się nie zmienia. 

 

Nie przypisuj tej samej zmiennej dla rożnych obrazków zwłaszcza że używasz LOCAL ! Ponumeruj sobie dla różnych plików $search1 dla t, $search2 dla d... itd   , to samo zrób ze zmiennymi jaki zwraca program , inne dla pierwszego wyniku , inne dla drugiego np x,y ( pierwszy ) a,b (drugi) itd 

 

Co do tego RETURN to zwróci tylko wynik działania funkcji czyli kod błędu albo np koordynaty, tutaj return nie służy do cofania tylko zwracania wartości/wyniku w momencie użycia.

Tylko jak przy tak dużym kodzie zrobić pętlę na całość? Już próbowałem na wiele sposobów i mi nie wychodzi. :<

Btw. wysłałem na PW source.

 

Kurde jak uda się to naprawić to obu Wam będę codziennie chociaż ten cholerny limit plusów dawać.

Męczę się z tym od wczoraj.

EDIT - UDAŁO mi się narzucić While 1 na cały kod, zobaczymy czy się zapętliło dobrze.

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Opublikowano

Autoit z tego co wiem nie oferuje optymalizacji ogonowej dla rekurencji, więc musisz wszystkie funkcje przerobić tak aby wykorzystywały zwykłe pętle:

 

Zamiast:

Func someFunction()
    ;jakiś kod
    someFunction()
EndFunc

Daj po prostu:

Func someFunction()
    While 1 ; lub daj tu jakiś warunek
        ;jakiś kod
    Wend
EndFunc

Możesz tez użyć dowolnej innej pętli - wszystkie działają podobnie.

Chcesz precyzyjnej i zrozumiałej odpowiedzi? - Zadaj precyzyjne i zrozumiałe pytanie. Nie przyjmuję zleceń.
Nie odpowiadam na priv na pytania, które można zadać na forum. Chcesz mojej pomocy - oznacz mnie w poście =>  @"Hans Kloss PL" 

Opublikowano

Autoit z tego co wiem nie oferuje optymalizacji ogonowej dla rekurencji, więc musisz wszystkie funkcje przerobić tak aby wykorzystywały zwykłe pętle:

 

Zamiast:

Func someFunction()
    ;jakiś kod
    someFunction()
EndFunc
Daj po prostu:

Func someFunction()
    While 1 ; lub daj tu jakiś warunek
        ;jakiś kod
    Wend
EndFunc
Możesz tez użyć dowolnej innej pętli - wszystkie działają podobnie.

 

Widzę po sygnaturze, że nie lubisz odpisywać na PW.

Dziękuję za pomoc, ale niestety nadal jej potrzebuję.

 

Tak ma to wyglądać?

	  Func PaliSie()
		 While 1
   			   global $y = 0, $x = 0
			   Local $searchPALISIE1 = _ImageSearch('PALISIE.bmp', 10, $x, $y, 0)
			   Sleep ( 15 )
			If $searchPALISIE1 = 1 Then
			   MouseClick( "PRIMARY", $x, $y )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 770, 422 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 830, 377 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 849, 421 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 905, 245 )
			   Sleep ( 100 )
			   PaliSie2()

	  EndIf
	  WEnd
	  EndFunc
	  Func PaliSie2()
		 While 1
   			   global $y = 0, $x = 0
			   Local $searchPALISIE2 = _ImageSearch('PALISIE.bmp', 10, $x, $y, 0)
			   Sleep ( 15 )
			If $searchPALISIE2 = 1 Then
			   MouseClick( "PRIMARY", $x, $y )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 770, 422 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 830, 377 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 849, 421 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 905, 245 )
			   Sleep ( 100 )
			   PaliSie3()
	 EndIf
	  WEnd
	  EndFunc
	  Func PaliSie3()
		 While 1
   			   global $y = 0, $x = 0
			   Local $searchPALISIE3 = _ImageSearch('PALISIE.bmp', 10, $x, $y, 0)
			   Sleep ( 15 )
			If $searchPALISIE3 = 1 Then
			   MouseClick( "PRIMARY", $x, $y )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 770, 422 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 830, 377 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 849, 421 )
			   Sleep ( 100 )
			   MouseClick( "PRIMARY", 905, 245 )
			   Sleep ( 100 )
			   PaliSie4()
			EndIf
			WEnd
	  EndFunc
Btw. cały src wysłałem na PW. :)

Wszystkie poradniki w "O mnie" i na moim profilu YouTube.


51dd70965ae71.png


!!!HIT!!! -- Pełno klientów na DT nawet na najstarszym kompie bez zamuły!


!!!HIT!!! -- Nowa modyfikacja do Metina FastKill


World of Metin2


Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...