Aller au contenu
San Andreas Multiplayer
C_far

Foreach & les fonctions de maniement d'un itérateur

Messages recommandés

Foreach & les fonctions de maniement d'un itérateur

Tutoriel vous expliquant le fonctionnement de l'include Foreach et les fonctions d'itérations y étant lié.

Ce tutoriel est dédié à Foreach 0.4.1.

Initiation :

Foreach est un mot-clé que l'on retrouve dans beaucoup de langages simplifiés aujourd'hui, malheureusement le Pawn n'y a pas eu le droit. C'est pourquoi Y_less nous a pondu une jolie include qui y est destiné.

Foreach est tout simplement une boucle fonctionnant avec des itérateurs, mais ça je vous l'expliquerai un peu plus loin dans le tutoriel.

Concrètement qu'est-ce que ça change de for et while ? Une grande optimisation mes amis !

Le mot-clé foreach et un itérateur :

 

  • Je vous choque si je vous dis que foreach n'est ni plus, ni moins qu'une macro utilisant for ?
    Ah ça vous en bouche un coin !
    Mais comment foreach utilisant for, peut-il être plus rapide que lui ?
    On en vient avec cette histoire d'itérateurs !
    Un itérateur est tout simplement un tableau dans lequel chaque case de ce tableau contient la valeur -1, elles sont donc invalides.
    Lorsque vous ajouterez une valeur positive et inférieure à la taille de votre itérateur, celle-ci s'ajoutera à la première case du tableau invalide.
    Il faut aussi prendre en compte que votre tableau tri les valeurs de la plus petite à la plus grande, cela signifie que si vous ajoutez la valeur 6, puis que vous ajoutez la valeur 5, votre foreach bouclera 2 fois et sortira en premier la valeur 5, alors que nous l'avons ajoutée après la valeur 6.
    Voici un exemple, ne cherchez pas encore à comprendre Iter_Add, nous verrons ça après :
 
#include 
#include 

new
	Iterator:Test<10>;

main()
{
	Iter_Add(Test, 6);
	Iter_Add(Test, 5);

	foreach(new i : Test)
	{
		printf("%d", i);
	}
}


Cela me printera :

 
5
6


Que si nous aurions utilisé for, nous aurions bouclé 10 fois. Certes, la rapidité n'est calculable qu'en nanosecondes, mais vous imaginez sur une boucle de 500 ou 2000 ? Foreach est vraiment une utilité !
Voilà, j'espère avoir été compris.
En fait, Foreach n'est rien sans les itérateurs, ce n'est qu'une macro semblable un peu à ça si je reprends mon exemple :

 
new
	Test[10] = {-1, ...};

main()
{
	Test[0] = 5;
	Test[1] = 6;

	for(new i = 0; i < 10 && Test[i] != -1; i++)
	{
		printf("%d", i);
	}
}


Simplement, vous n'avez pas à vous casser la tête avec des comparaisons. L'include peut vous paraître complexe seulement au niveau des instructions des fonctions maniant les itérateurs. Heureusement, Dutheil les a étudiées pour vous et va vous les expliquer, on se retrouve après la pub !

 

Les fonctions maniant les itérateurs:

 

  • Fonction » Iter_Add:
Révélation

 

  • Cette fonction permet d'ajouter une valeur à un itérateur, elle contient 2 paramètres :
  1. Le nom de l'itérateur
  2. La valeur

 

Elle peut retourner 2 valeurs :

 

  1. - Si vous la valeur ajoutée est inférieure à 0 ou supérieure à la taille de l'itérateur ou que l'itérateur est déjà complet
  2. 1 - Si la fonction s'est exécutée avec succès

 

Exemple d'utilisation :

 

 

Iter_Add(Test, 6);


Ici on ajoute la valeur 6 à l'itérateur Test.

 

 

 

  • Fonction » Iter_Remove:
Révélation

 

  • Cette fonction permet de retirer une valeur d'un itérateur, elle contient 2 paramètres :
  1. Le nom de l'itérateur
  2. La valeur

 

Elle peut retourner 2 valeurs :

 

  1. - Si vous la valeur ajoutée est inférieure à 0 ou supérieure à la taille de l'itérateur ou que l'itérateur est vide
  2. 1 - Si la fonction s'est exécutée avec succès

 

Exemple d'utilisation :

 

 

Iter_Remove(Test, 6);


Ici on retire la valeur 6 à l'itérateur Test.

 

 

 

  • Fonction » Iter_Free:
Révélation

 

  • Cette fonction retourne la plus petite valeur qui n'est pas dans l'itérateur, elle contient 1 paramètre :
  1. Le nom de l'itérateur

 

Elle peut retourner deux types de valeur :

 

  1. -1 - Si l'itérateur est complet
  2. La plus petite valeur qui n'est pas dans l'itérateur

 

Exemple d'utilisation :

 

 

new
	variable = Iter_Free(Test);


Si l'itérateur contient les valeurs : 0, 1, 3, 5, 8, la fonction retournera 2.

 

 

 

  • Fonction » Iter_Contains:
Révélation

 

  • Cette fonction permet de savoir si un itérateur contient une valeur indiquée, elle contient 2 paramètres :
  1. Le nom de l'itérateur
  2. La valeur

 

Elle peut retourner 2 valeurs :

 

  1. - Si l'itérateur ne contient pas la valeur
  2. 1 - Si l'itérateur contient la valeur

 

Exemple d'utilisation :

 

 

if(Iter_Contains(Test, 6))
{
	print("Yes !");
}


Si l'itérateur contient les valeurs : 0, 2, 4, 6, 8, la fonction retournera 1 et le code affichera donc "Yes !".

 

 

 

  • Fonction » Iter_Count:
Révélation

 

  • Cette fonction retourne le nombre de valeurs contenues dans un itérateur, elle contient 1 paramètre :
  1. Le nom de l'itérateur

 

Exemple d'utilisation :

 

 

printf("%d", Iter_Count(Test));


Si l'itérateur contient les valeurs : 0, 1, 3, 4, 7, la fonction retournera 5.

 

 

 

  • Fonction » Iter_Random:
    Cette fonction retourne une valeur au hasard contenue dans un itérateur, elle contient 1 paramètre :
  1. Le nom de l'itérateur

 

Elle peut retourner deux types de valeur :

 

  1. -1 - Si l'itérateur est vide
  2. Une valeur au hasard contenue dans l'itérateur

 

Exemple d'utilisation :

 

 

print("%d", Iter_Random(Test));


Bon là j'peux pas vous dire ce que retournera la fonction, c'est random :mrgreen:.

 

 

 

Des itérateurs prêts à l'utilisation:

Voici une liste des itérateurs tout prêts à être utilisés avec foreach :

 

  • Player - Itérateur des joueurs connectés.
  • Bot - Itérateur des bots connectés.
  • NPC - Alias de Bot.
  • Character - Itérateur des joueurs et bots connectés.

 

Constantes supplémentaires:

Deux constantes s'offrent à vous, elles sont à définir avant d'inclure foreach.

FOREACH_NO_BOTS

 

  • Ne crée pas l'itérateur Bot, NPC et Character


FOREACH_NO_PLAYERS

 

  • Ne crée pas l'itérateur Player et Character

 

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Il est pas mal cet include, je viens de look le fichier. Il y a une fonction safe remove aussi pour remove pendant l'itération. Pas testé par contre, mais ca peut etre utile.

Partager ce message


Lien à poster
Partager sur d’autres sites
il y a 9 minutes, Hodor a dit :

Il est pas mal cet include, je viens de look le fichier. Il y a une fonction safe remove aussi pour remove pendant l'itération. Pas testé par contre, mais ca peut etre utile.

Il y a des fonctions que je n'ai pas précisées dans ce sujet comme ;

  • Iter_Clear
  • Iter_Begin
  • Iter_End
  • Iter_First
  • Iter_Last
  • Iter_Next
  • Iter_Prev
Function:
	Iter_Clear
Params:
	iter - Name of the iterator empty.
Notes:
	Wrapper for Iter_ClearInternal.

------------------------------------------------------------------------------------	
	
Function:
	Iter_Begin
Params:
	iter - Name of the iterator to get the start of.

Notes:
	Gets a point BEFORE the start of the iterator (the theoretical beginning).

------------------------------------------------------------------------------------
	
Function:
	Iter_End
Params:
	iter - Name of the iterator to
	
Notes:
	Gets a point AFTER the end of the iterator (think "MAX_PLAYERS").

------------------------------------------------------------------------------------
	
Function:
	Iter_First
Params:
	iter - Name of the iterator to
Notes:
	Gets the first element in an iterator.
	
------------------------------------------------------------------------------------	
	
Function:
	Iter_Last
Params:
	iter - Name of the iterator to
Notes:
	Gets the last element in an iterator.

------------------------------------------------------------------------------------	
	
Function:
	Iter_Next
Params:
	iter - Name of the iterator to
Notes:
	Gets the element in an interator after the current one.

------------------------------------------------------------------------------------
	
Function:
	Iter_Prev
Params:
	iter - Name of the iterator to
Notes:
	Gets the element in an iterator before the current one.  Slow.

 

Partager ce message


Lien à poster
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant

×