Autoit Problème avec FastFind

Inscrit
15 Avril 2011
Messages
457
Reactions
1
#1
Tout est dans l'image, j'aimerais savoir la cause de l'erreur.
 
A

Anonymous

Invité
#2
Tu apprends a utiliser un traducteur et tu as ta réponse ;)
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#3
Merci, mais "le niveau de récursivité a excédé", je sais pas trop ce que ça veut dire...
 
A

Anonymous

Invité
#4
Montre nous le debut de ton script
 

Geraff

Administrateur
Membre du personnel
Inscrit
13 Mars 2008
Messages
564
Reactions
0
#5
Tu fait appel à une fonction récursive, c'est une fonction qui s’appelle elle même avec un paramètre qui change, elle ne dispose que d'un cas de retour généralement.

Tu as fait X appel récursif et la le programme te dis va chier et à laché l'affaire (en C# c'est limité à 100 boucles récursives à la fois il me semble).

Donc tu as un problème avec ton appel récursif il doit y avoir une erreur quelque part, soit l'appel de l’arrêt de la fonction est mauvais, soit tu ne sai spas t'en servir correctement, soit tu ne cherches pas ce qu'il faut.
 
Inscrit
19 Octobre 2010
Messages
214
Reactions
0
#6
Tout est dit, ou presque.

Le message t'indique que l'erreur est détectée dans AutoIt : le problème n'est donc pas dans la dll FastFind.

De mémoire, le wrapper AutoIt de FastFind ne fait pas d'appels récursifs, donc il est aussi hors de cause.

Je dirais que dans un programme bien fait, on utilise très rarement la récursion. Donc si tu peux, évites. Et si tu peux pas, ben assures-toi que ta fonction récursive ne risque jamais de boucler indéfiniment.

Exemple de fonction récursive (code C/C++/C#):

Code:
int factoriel(int n)
{
if (n<=1) 
   return 1;
else
   return n * factoriel(n-1);
}
Dans cet exemple, si n <= 1 on ne boucle pas, et dans le cas contraire on boucle (n-1) fois.

Mais c'est toujours plus performant et plus fiable de transformer les fonctions récursives en fonctions itératives (avec une boucle), ce qui est à peine plus long à coder.
Code:
int factoriel(int n)
{
int result = 1;
for (int i = n; i>1; i--)  result *= i;
return result;
}
 
Inscrit
19 Octobre 2010
Messages
214
Reactions
0
#7
Geraff a dit:
(en C# c'est limité à 100 boucles récursives à la fois il me semble)
Heureusement pas ! Même dans un langage de script comme Autoit, l'auteur ne se permettrait pas de mettre une telle limite aussi ridiculement faible en dur.

Dans tous les langages - et C# ne semble pas faire exception - le niveau de récursion dépend essentiellement de la taille de la pile. Le nombre de récursions n'est donc pas fixe, mais dépend de la quantité de variables locales et d'arguments passés dans la fonction.
 

Geraff

Administrateur
Membre du personnel
Inscrit
13 Mars 2008
Messages
564
Reactions
0
#8
Yep pardon, c'est 1Mb la pile d'appel par défaut en C#.
et j'ai trouvé 10000 appels comme ordre d'idée mais je ne sais pas ce que ça vaut.
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#9
Salut, merci pour vos réponses. Mais je pense que pour régler le problème, il faut que je change radicalement mon code...

Voici la fonction utilisée et qui plante au bout d'un certain temps :
Code:
Func rechercheMonstre($couleurmob)
	$mob_a=FFNearestPixel(0,0,$couleurmob,true,439,652,1316,734)
	If @error=1 Then
		Return 0
	Else
		Return $mob_a
	EndIf
EndFunc

Et voici la fonction combat de mon bot :

Code:
Local $cbt=0
Local $nombreAttaques=0
Local $possible=1
Local $nombreCombats=0

Func combat($couleurmob)          ; fct combat principale
	If $cbt=0 Then
		debutcombat()			; on lance la fct de début de combat
	EndIf
		detecterTour() 							; savoir si c'est son tour
		trouveMonstre($couleurMob) ; on va chercher le mob ---> fct complémentaire
EndFunc

Func debutcombat()          ; fct de debut de cbt
	pret()					; appuie sur le bouton pret
	Sleep(5000)
	$cbt=1
EndFunc

Func trouveMonstre($couleurMob) ; fonction complémentaire pour trouver le mob à attaquer
   Local $trouve=0
   While $trouve=0 ; tq pas de mob trouvé
	$trouve=rechercheMonstre($couleurmob) ; on cherche le mob
	If $trouve=0 Then ; si  non trouvé
		$nombreAttaques=0
		passerTour()
		Sleep(1000)
		supprimerAiresExclues()
		$possible=1
		combat($couleurmob)
	Else
		possibiliteAttaque($couleurMob)
	EndIf
   WEnd
EndFunc

Func possibiliteAttaque($couleurMob)
	If $possible=1 Then
		cliquerSort()
	EndIf
	Sleep(500)
	pointerMonstre($mob_a)
	Sleep(1000)
	$possible=attaquePossible($mob_a); on cherche à savoir si on peut l'attaquer
	If $possible=0 Then ; si impossible
		exclureAire($mob_a)
		trouveMonstre($couleurMob)
	Else
		supprimerAiresExclues()
		$possible=1
		attaquerMonstre($couleurMob)
   EndIf
EndFunc

Func attaquerMonstre($couleurMob)
	If $nombreAttaques=0 Then
		lancerSort($mob_a)
		Sleep(3000)
		$nombreAttaques+=1
		$test=rechercheMonstre($couleurmob)
			If $test=0 Then
				Sleep(2000)
				finCombat($couleurmob)
			EndIf
		trouveMonstre($couleurMob)
	Else
		lancerSort($mob_a)
		Sleep(500)
		$nombreAttaques=0
		passerTour()
		barreTourAbsente() 							; on attend que la barre de tour disparaisse
		Sleep(3000)
		finCombat($couleurmob)
		combat($couleurmob)
	EndIf
EndFunc

Func finCombat($couleurmob)
	If PixelGetColor(735,627)=0xFF6100 Then       											; si le bouton pour fermer la fenêtre de combat est présent
		Sleep(500)
		MouseClick("left",735,627,1,0)  													; alors on clique dessus
		Sleep(500)																			; on attends un peu qu'elle se ferme
		$nombreCombats+=1																	; on incrémente la variable du nombre de combats de 1 pour compter les combats
		If PixelGetColor(873,766)=0x322D25 Then												; si le perso est à la moitié de sa vie (environ)
			MouseClick("left",325,740,1,0)													; alors on ouvre la fenêtre des émotes
			Sleep(2000)																		; on attend un peu qu'elle s'ouvre
			MouseClick("left",330,660,1,0)													; on clique sur l'émote s'asseoir pour se reposer
			Sleep(3000)																		; on attend que le personnage soit assis
			MouseClick("left",325,740,1,0)													; on ferme la fenêtre des émotes
			Do
				Sleep(10)																	; on attend
			Until PixelGetColor(867,749)=0xFF0000	 										; jusqu'à ce qu'il ait repris assez de vie
		EndIf
		$cbt=0																				; ------> A TESTER !!!!!!!!!!!!!!!!
		testInventaire()
		main()																				; et on relance la boucle de recherche de nouveau combat
	EndIf
EndFunc

Func quitter()																				; fonction qui peut être déclencher exclusivement par l'utilisateur
	MsgBox(0,"Nombre de combats",$nombreCombats)											; affiche une boîte de dialogue affichant le nombre de combat effectué
	Exit																					; stop le script définitivement
EndFunc

Désolé, c'est pas tout le temps expliqué, et c'est un peu le bordel. Mais comme vous pouvez le voir, les fonctions s'appellent les unes les autres, ça fait que les variables sont jamais libérées de la pile, et je pense que c'est pour ça qu'elle plante... :S Je ne sais pas comment résoudre ça sans modifier totalement mon code :/
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#10
J'ai une question : si une fonction fait appelle à une autre sans que cette dernière ne lui adresse de retour, est-ce que ça compte comme récursivité ?
 
Inscrit
19 Octobre 2010
Messages
214
Reactions
0
#12
combat => trouveMonstre => combat => trouveMonstres => combat => trouveMonstre....

Tu empiles ainsi les appels récursifs si le monstre n'est pas trouvé. Il y a un problème de logique.

Il faut transformer ton code pour éviter la récursion. Une boucle fait ça très bien.
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#13
J'ai modifié mon code, j'ai retiré toute la récursivité et les appels de fonctions sans retour, je ne devais plus avoir de problème^^, merci !
 
Haut Bas