←  Gotowe funkcje

AMXX.pl: Support AMX Mod X i SourceMod

»

Foreach i Forrange implementacja pętli uła...

  • +
  • -
DarkGL - zdjęcie DarkGL 09.06.2013

http://darkgl.amxx.p...iajacych-zycie/
 
Często podczas prac nad pluginem w kodzie muszę „przeliterować” po elementach tablicy czy wszystkich graczach. Pisanie rozbudowanej pętli for jest meczące i nużące więc pomyślałem że foreach znane z php było by znacznym ułatwieniem.
 
http://php.net/manua...res.foreach.php
 
Najpierw opis samych funkcji ( które są tak naprawdę makrodefinicjami )
  • foreach – „przeliterowuje” po całej tablicy i przypisuje wartość aktulnie używanego elementu do zdefiniowanej zmiennej
    dwa parametry
    • 1 – tablica po której ma literować
    • 2 – nazwa zmiennej do której będzie zapisywany aktualny element
  • forrange2 – wylicza kolejne wartości liczbowe i przypisuje je do zmiennej. Inspirowalem się funkcją range w php i python
    dwa parametry ( liczba po nazwie określa ilość parametrów )
    • 1 – nazwa zmiennej do które będzie zapisywana aktualna wartość
    • 2 – górny indeks do którego nastąpi odliczanie, odliczanie startuje od 0 do właśnie tego parametru – 1 z krokiem inkrementacyjnym równym 1 np. 0 , 1 , 2 , 3
  • forrange3 – to samo co funkcja wyżej
    Trzy parametry
    • 1 – nazwa zmiennej
    • 2 – dolny indeks od którego zacznie się odliczanie
    • 3 – górny indeks tak jak parametr 2 w funkcji forrange2
      Przykład dla dolnego indeksu równego 3. 3 , 4 , 5 , 6
  • forrange4 – To samo co funkcje wyżej
    Cztery parametry
    • 1- nazwa zmiennej
    • 2- dolny indeks tak jak w forrange3
    • 3 – górny indeks tak jak w forrange3
    • 4- krok inkrementacji np. możemy ustawić go na 10 więc liczby bedą się zwiększac o 10 co każdy krok
      Przykład 0 , 10 , 20 , 30 , 40 , 50
Definicje które trzeba dodać do pluginu
 
 
#define foreach(%1,%2) for( new iCurrentElement = 0 , %2 = %1[ 0 ]; iCurrentElement < sizeof %1 ; iCurrentElement++ , %2 = iCurrentElement < sizeof %1 ? %1[ iCurrentElement ] : 0 )
#define forrange4(%1,%2,%3,%4) for( new %1 = %2; %1 < %3 ; %1 += %4 )        

#define forrange3(%1,%2,%3) for( new %1 = %2; %1 < %3 ; %1 += 1 )
    
#define forrange2(%1,%2) for( new %1 = 0; %1 < %2 ; %1 += 1 )
 
Przykład użycia
 
#include <amxmodx>
#include <amxmisc>

#define PLUGIN    "New Plugin"
#define AUTHOR    "DarkGL"
#define VERSION    "1.0"

#define foreach(%1,%2) for( new iCurrentElement = 0 , %2 = %1[ 0 ]; iCurrentElement < sizeof %1 ; iCurrentElement++ , %2 = iCurrentElement < sizeof %1 ? %1[ iCurrentElement ] : 0 )

#define forrange4(%1,%2,%3,%4) for( new %1 = %2; %1 < %3 ; %1 += %4 )        

#define forrange3(%1,%2,%3) for( new %1 = %2; %1 < %3 ; %1 += 1 )
    
#define forrange2(%1,%2) for( new %1 = 0; %1 < %2 ; %1 += 1 )
    
public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR)
    
    new testArray[] = { 1 , 2 , 3 , 4 };
    
    foreach( testArray , value ){
        log_amx( "each %d" , value );
    }
    
    log_amx( "Range 1" );
    
    forrange2( value , 5 ){
        log_amx( "range1 %d" , value );
    }
    
    log_amx( "Range 2" );
    
    forrange3( value , 1 , 5 ){
        log_amx( "range2 %d" , value );
    }
    
    log_amx( "Range 3" );
    
    forrange4( value , 0 , 100 , 10 ){
        log_amx( "range3 %d" , value );
    }
}
 
Zwracane wartości
 
[testFor.amxx] each 1
[testFor.amxx] each 2
[testFor.amxx] each 3
[testFor.amxx] each 4
[testFor.amxx] Range 1
[testFor.amxx] range1 0
[testFor.amxx] range1 1
[testFor.amxx] range1 2
[testFor.amxx] range1 3
[testFor.amxx] range1 4
[testFor.amxx] Range 2
[testFor.amxx] range2 1
[testFor.amxx] range2 2
[testFor.amxx] range2 3
[testFor.amxx] range2 4
[testFor.amxx] Range 3
[testFor.amxx] range3 0
[testFor.amxx] range3 10
[testFor.amxx] range3 20
[testFor.amxx] range3 30
[testFor.amxx] range3 40
[testFor.amxx] range3 50
[testFor.amxx] range3 60
[testFor.amxx] range3 70
[testFor.amxx] range3 80
[testFor.amxx] range3 90
 
Jak widać funkcje znacznie ułatwiają przeglądanie tablic po za tym kod wygląda lepiej.
na wstępie mówiłem o

po elementach tablicy czy wszystkich graczach

jak widać najlepiej zastosowac tu funkcje forrange3
 
 
forrange( currentPlayerID , 1 , 33 )
( zamiast stałej 33 można też wstawić pobieranie ilości slotów )
Użytkownik DarkGL edytował ten post 09.06.2013 02:46
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 09.06.2013

Przepraszam, czy jest na forum ranga "Wymiatacz"? Albo "Geniusz"? Albo "Bóg"?... Nie? ... A mógłby ktoś utworzyć i przydzielić ją temu człowiekowi?

 

Jakbym nie był tak leniwy, to pewnie sam bym to zrobił, ale niestety... jestem :D

Odpowiedz

Pan Marian - zdjęcie Pan Marian 09.06.2013

DarkGL dzień jak co dzień na patencie

Odpowiedz

  • +
  • -
dasiek - zdjęcie dasiek 09.06.2013

Kocham Cię Dark. :*

Odpowiedz

  • +
  • -
sebul - zdjęcie sebul 09.06.2013

Przyda się, niby to tylko po prostu ułatwia używanie pętli, no ale jednak to zawsze coś. Sam nie wpadłbym, żeby coś takiego zrobić, bo jednak do takich rzeczy trzeba mieć jakiś bodziec. Ogólnie przydało by się zrobić listę funkcji, których nie ma w pawnie, a mogą być przydatne i wtedy brać się do roboty za pisanie makrodefinicji lub funkcji.
Odpowiedz

  • +
  • -
Kewin. (ZeZ) - zdjęcie Kewin. (ZeZ) 17.06.2013

Zna ktoś jakiś temat gdzie jest wytłumaczona funkcja "for" ?

A jesli takiej nie ma, to prosilbym o wytlumaczenie :)

Odpowiedz

  • +
  • -
sebul - zdjęcie sebul 17.06.2013

Zna ktoś jakiś temat gdzie jest wytłumaczona funkcja "for" ?
A jesli takiej nie ma, to prosilbym o wytlumaczenie :)

pętla for
Odpowiedz

  • +
  • -
sebul - zdjęcie sebul 19.10.2013

Teraz tak tylko patrzę, czemu "%1 += 1", a nie "++%1"?
Odpowiedz

  • +
  • -
DarkGL - zdjęcie DarkGL 19.10.2013

przez %1 += %4 i moje lenistwo ;>

Odpowiedz

  • +
  • -
sharkowy - zdjęcie sharkowy 21.10.2013

Nie wiem o co chodzi, ale podoba mi się to.

Odpowiedz

GT Team - zdjęcie GT Team 21.10.2013

Takie pytanie, zapewne grałeś kiedyś w Colobot ( jak nie to polecam ! ). Tam jest taka funkcja
repeat(num)
W której wykonuje się czynnośc określoną ilość razy np
new i;
repeat(5)
{
     client_print(0,3,"%d", ++i);
}
Która funkcja najlepiej odwzorowuje to, albo jak stworzyc takie coś ? Tak?
#define repeat(%1) for(new i = 1;  i <= %1; i++)

sebul (21.10.2013 22:12):
Tak.
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 21.10.2013

forrange2(i, 5) zadziała dokładnie tak, jak repeat(5)

Odpowiedz

GT Team - zdjęcie GT Team 22.10.2013

Ale jest tam zmienna i, która jest nie potrzebna;p ( Mówimy o wersji z Colobot )
Odpowiedz

  • +
  • -
DarkGL - zdjęcie DarkGL 23.10.2013

Narzut pamięciowy i czasowy w takim przypadku jest pomijalny colobot też tak pewnie robił tylko nie miałeś dostępu do zmiennej , chyba że "kopiował" kod x razy  ;>

Odpowiedz