Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 4 1 2 3 ... ПоследняяПоследняя
Показано с 1 по 10 из 31
  1. #1
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±

    Итераторы в Pawn

    foreach - одна из библиотек проекта YSI (y_iterate), добавляющая возможность создавать собственные итераторы. Из-за особенностей алгоритма процесс итерирования может проходить намного быстрее простого перебора. Помимо этого, библиотека имеет обширный функционал.

    Как было сказано выше, библиотека является частью проекта YSI, но, тем не менее, существует версия без зависимости от YSI. Отличие заключается лишь в том, что на данный момент только версия из YSI поддерживается самим разработчиком.

    Ограничения и особенности алгоритма
    Некоторые ограничения:
    • В итератор не могут входить числа меньше нуля и больше, чем размер итератора.
    • В итераторе все числа идут по порядку, кроме самого меньшего (он расположен в самом конце итератора)


    Алгоритм и его особенности
    Дело в том, что при инициализации итератора вы создаёте всегда на одну ячейку больше. Эта ячейка будет содержать размер итератора (не всегда, см. выше); она также помогает определить границу итератора при итерировании.

    Итерирование происходит так: сначала читается последний элемент, если он не равен размеру итератора, то значение в ячейке записывается. Затем происходит ещё одна итерация, теперь уже сравнивается размер и значение элемента массива с индексом записанного числа и так много раз, пока значение элемента не будет равно размеру итератора. Поэтому вы не можете указывать числа больше размера итератора или меньше нуля, т.к. это нарушит алгоритм и вызовет ошибки.



    Как видим, все остальные ячейки заполняются числами больше размера массива, это делается для того, чтобы поместить в последнюю ячейку именно размер.

    Создание итераторов
    Обычный итератор
    Для создания такого итератора необходимо знать только шаблон макроса.
    Код:
    Iterator:name<10>
    name - имя итератора.
    10 - размер итератора.

    Предостережения:
    • Макрос на самом деле генерирует сразу две переменные: переменную с количеством действующих элементов, а также сам массив.
    • Массив заполняется значениями при его декларировании, следовательно, вы не сможете установить собственные значения.
    • К имени прибавляется суффиксы "@YSII_Cg" для переменной с количеством элементов и "@YSII_Ag" для массива.

    Многомерные итераторы
    Для создания многомерных итераторов необходимо знать не только шаблон, но и функцию заполнения, поскольку массивы не могут быть инициализированы под алгоритм во время компиляции.

    Рассмотрим шаблон:
    Код:
    IteratorArray:name[12]<10>
    name - имя итератора.
    12 - размер первого итератора.
    10 - размер второго итератора.

    Предостережения:
    • Макрос на самом деле генерирует сразу две переменные: массив с количеством действующих элементов для каждого массива, а также сам многомерный массив.
    • Необходимо инициализировать функцией.
    • К имени прибавляется суффиксы "@YSII_Cg" для переменной с количеством элементов и "@YSII_Ag" для массива.

    Пример инициализации:
    PHP код:
    new IteratorArray:PlayerObjects[MAX_PLAYERS]<10>;

    public 
    OnGameModeInit() {
        
    Iter_Init(PlayerObjects);


    Документация и использование итераторов
    Документация к функциям
    В библиотеке присутствует множество разнообразных функций, помогающих в работе с итераторами.

     Документация к функциям
    Название Описание
    Iter_Init Инициализирует многомерные итераторы.

    Параметры:
    • name - имя итератора

    Возвращает:
    Всегда нуль.
    Iter_Add Добавляет новое значение в итератор.

    Параметры:
    • name - имя итератора
    • value - добавляемое значение

    Возвращает:
    В случае успеха возвращает истину, иначе ложь.
    Iter_Free Находит свободный слот в итераторе.

    Параметры:
    • name - имя итератора

    Возвращает:
    Индекс свободного слота.
    Iter_Remove Удаляет значение из итератора

    Параметры:
    • name - имя итератора
    • value - удаляемое значение

    Возвращает:
    В случае успеха возвращает истину, иначе ложь.
    Iter_Contains Проверяет наличие значения в итераторе

    Параметры:
    • name - имя итератора
    • value - проверяемое значение

    Возвращает:
    В случае успеха возвращает истину, иначе ложь.
    Iter_SafeRemove Безопасно удаляет значение из итератора.

    Параметры:
    • name - имя итератора
    • value - удаляемое значение
    • next - индекс на следующий элемент.

    Возвращает:
    В случае успеха возвращает истину, иначе ложь.
    Iter_Random Случайно определяет число из итератора.

    Параметры:
    • name - имя итератора

    Возвращает:
    Случайное число из итератора
    Iter_Count Количество добавленных элементов.

    Параметры:
    • name - имя итератора

    Возвращает:
    Количество добавленных элементов.
    Iter_Clear Освобождает итератор от всех значений.

    Параметры:
    • name - имя итератора

    Возвращает:
    Всегда нуль.
    Iter_First Получает первый элемент в итераторе.

    Параметры:
    • name - имя итератора

    Возвращает:
    Возвращает индекс.
    Iter_Last Получает последний элемент в итераторе.

    Параметры:
    • name - имя итератора

    Возвращает:
    Возвращает индекс.
    Iter_Next Получает следующий элемент в итераторе.

    Параметры:
    • name - имя итератора
    • current - текущий индекс.

    Возвращает:
    Возвращает следующий индекс.
    Iter_Prev Получает предыдущий элемент в итераторе.

    Параметры:
    • name - имя итератора
    • current - текущий индекс.

    Возвращает:
    Возвращает следующий индекс.
    Iter_InternalArray Получает доступ к массиву.

    Параметры:
    • name - имя итератора.

    Возвращает:
    -
    Iter_InternalSize Получает действительный размер массива.

    Параметры:
    • name - имя итератора.

    Возвращает:
    Размер массива.


    Созданные итераторы
    В библиотеке присутствуют уже созданные итераторы такие как: Player, Vehicle, Bot, NPC (то же самое, что и Bot), Character (NPC и игроки). Поэтому вам не придётся создавать их снова.

    Псевдооператор foreach
    Именно с помощью данного оператора и происходит итерирование. Данный оператор схож с range-based циклами в С++11. Однако у foreach есть и старая версия синтаксиса, которую не рекомендуют использовать. Кстати, в новой версии библиотеки она всё ещё присутствуют, но, тем не менее, при использовании появляется предупреждение, говорящее как раз об этом. Поэтому в данном уроке его не будет.

    Рассмотрим синтаксис:
    Код:
    foreach(new i : Player)
    new - спецификатор, говорящий о том, что необходимо создать новую переменную.
    i - название переменной, в которую будет записываться значение из итератора. Оно может быть абсолютно любое.
    Player - название итератора, из которого мы будет брать значения.


    Примеры использования
    Пример №1
    Допустим, что нам нужно сделать определённый массив, в котором будут храниться идентификаторы администраторов. С помощью этого массива мы, например, будет отправлять сообщения всем администраторам. Как раз для этого и необходимы итераторы.

    Создадим итератор, например, с названием ConnectedAdmins.
    PHP код:
    new Iterator:ConnectedAdmins<MAX_PLAYERS>; 
    Далее создадим функцию отправки сообщения этим администраторам:
    PHP код:
    stock SendAdminMessage(adminidcolor, const message[])
    {
        foreach(new 
    ConnectedAdmins) {
            
    SendClientMessage(icolormessage);
        }

    Теперь нам остаётся сделать только добавление/удаление идентификаторов в итератор при входе/выходе администратора.

    Пример №2
    Итак. Суть данного примера заключается в том, что мы должны вывести цифры в обратном порядке, т.е. сделать простой обратный цикл.

    Создадим итератор, например, с названием Nums. Он будет содержать, допустим, 10 ячеек.
    PHP код:
    new Iterator:Nums<10>; 
    В библиотеки не оказалось обратного цикла, поэтому мы сделаем свой:
    PHP код:
    stock PrintNums() {
        for (new 
    Iter_End(Nums); (Iter_Prev(Numsi)) != Iter_Begin(Nums);)
            
    printf("%d"i);

    Нам осталось лишь загрузить значения и скомпилировать.

    Пример №3
    Создадим скрипт, суммирующий счёт каждой команды. В нём нам необходимо использовать массива итераторов.
    PHP код:
    #define MAX_TEAMS 255

    new
        
    Iterator:Team[MAX_TEAMS]<MAX_PLAYERS>;

    public 
    OnGameModeInit()
    {
        
    Iter_Init(Team);

        
    #if defined Team_OnGameModeInit
            
    return Team_OnGameModeInit();
        
    #else
            
    return 1;
        
    #endif
    }
    #if defined _ALS_OnGameModeInit
        #undef OnGameModeInit
    #else
        #define _ALS_OnGameModeInit
    #endif

    #define OnGameModeInit Team_OnGameModeInit
    #if defined Team_OnGameModeInit
        
    forward Team_OnGameModeInit();
    #endif



    stock Team_SetPlayerTeam(playeridteamid)
    {
        new 
    current_team GetPlayerTeam(playerid);
        if (
    current_team != NO_TEAM) {
            
    Iter_Remove(Team[current_team], playerid);
        }

        if (
    teamid != NO_TEAM) {
            
    Iter_Add(Team[teamid], playerid);
        }

        return 
    SetPlayerTeam(playeridteamid);
    }
    #if defined _ALS_SetPlayerTeam
        #undef SetPlayerTeam
    #else
        #define _ALS_SetPlayerTeam
    #endif

    #define SetPlayerTeam Team_SetPlayerTeam 
    Использовать так:
    PHP код:
    new scores[MAX_TEAMS];
    for (new 
    teamidteamid MAX_TEAMSteamid++) {
        foreach (new 
    playerid Team[teamid]) {
            
    scores[teamid] += GetPlayerScore(playerid);
        }
    }

    for (new 
    teamidteamid MAX_TEAMSteamid++) {
        
    printf("Team %d: %d"teamidscores[teamid]);


    Разные версии
    Существует две версии данной библиотеки:
    • foreach - автономная версия, не зависящая от других инклудов. Если вы не используете YSI, то можете смело скачивать эту версию. Автор (Y_Less) отказался поддерживать этот инклуд, поэтому форки инклуда есть сразу у нескольких представителей сообщества SA-MP - на момент написания наиболее актуальный форк можно найти у ziggi.
      Отличается данная версия наличием итераторов для актёров и транспорта (в том числе итераторов Stream, которые выключены по умолчанию), поддержкой множественных скриптов (FS + GM), оптимизированным ALS (без использования CallLocalFunction) и отсутствием поддержки npcmodes (для более чистого кода).
    • y_iterate - это версия, поддерживаемая самим разработчиком YSI. Однако, чтобы использовать её, необходимо скачать полностью весь проект YSI, ибо она привязана к другим инклудам. Таким образом, если вы используете YSI в своём проекте, то вам больше подойдёт y_iterate.

    Скачать:
    Для скачивания на открывшейся странице нажмите на кнопку "Clone or download" (зелёного цвета) и в открывшемся меню - "Download ZIP".


    Статью подготовил: VVWVV

    Исключительно для pro-pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Последний раз редактировалось VVWVV; 28.04.2017 в 21:45. Причина: -

  2. 4 пользователя(ей) сказали cпасибо:
    LowRider (11.06.2017) Nexius_Tailer (18.09.2019) Nurick (02.04.2017) wAx (12.02.2018)
  3. #2
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Предложу свой форк standalone библиотеки: https://github.com/Open-GTO/foreach/releases
    Отличается наличием итераторов для актёров и транспорта (в том числе Stream итераторов, которые выключены по умолчанию), поддержкой множественных скриптов (FS + GM), оптимизированным ALS (без использования CallLocalFunction) и отсутствием поддержки npcmodes (для более чистого кода).

    P.S. Не увидел примера использования массивов итераторов, предложу свой: https://github.com/Open-GTO/foreach#...y-of-iterators
    Массив итераторов с игроками в команде:
    PHP код:
    #define MAX_TEAMS 255
    #define MAX_PLAYERS_IN_TEAM MAX_PLAYERS / MAX_TEAMS

    new
        
    Iterator:Team[MAX_TEAMS]<MAX_PLAYERS_IN_TEAM>;

    public 
    OnGameModeInit()
    {
        
    Iter_Init(Team);

        
    #if defined Team_OnGameModeInit
            
    return Team_OnGameModeInit();
        
    #else
            
    return 1;
        
    #endif
    }
    #if defined _ALS_OnGameModeInit
        #undef OnGameModeInit
    #else
        #define _ALS_OnGameModeInit
    #endif

    #define OnGameModeInit Team_OnGameModeInit
    #if defined Team_OnGameModeInit
        
    forward Team_OnGameModeInit();
    #endif



    stock Team_SetPlayerTeam(playeridteamid)
    {
        new 
    current_team GetPlayerTeam(playerid);
        if (
    current_team != NO_TEAM) {
            
    Iter_Remove(Team[current_team], playerid);
        }

        if (
    teamid != NO_TEAM) {
            
    Iter_Add(Team[teamid], playerid);
        }

        return 
    SetPlayerTeam(playeridteamid);
    }
    #if defined _ALS_SetPlayerTeam
        #undef SetPlayerTeam
    #else
        #define _ALS_SetPlayerTeam
    #endif

    #define SetPlayerTeam Team_SetPlayerTeam 
    Использовать так:
    PHP код:
    new scores[MAX_TEAMS];
    for (new 
    teamidteamid MAX_TEAMSteamid++) {
        foreach (new 
    playerid Team[teamid]) {
            
    scores[teamid] += GetPlayerScore(playerid);
        }
    }

    for (new 
    teamidteamid MAX_TEAMSteamid++) {
        
    printf("Team %d: %d"teamidscores[teamid]);

    Этот скрипт суммирует счёт каждой команды и выводит его
    Последний раз редактировалось ziggi; 24.03.2017 в 07:56.

  4. #3
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Нельзя создавать "контейнер" по типу: ключ | значение (str)?
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  5. #4
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    И не хватает примера с трехмерными массивами (взято отсюда, ибо я ленивый):
    PHP код:
    new
        
    Iterator:Iter3[5][8]<10>;
    for (new 
    0!= Iter_InternalSize(Iter3); ++i)
    {
        
    Iter_Init(Iter3[i]);
    }
    Iter_Add(Iter3[3][6], 7); 
    Лишней такая информация не будет
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  6. Пользователь сказал cпасибо:
    execution (21.02.2020)
  7. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    Нельзя создавать "контейнер" по типу: ключ | значение (str)?
    Статья про итераторы, а не про ассоциативные массивы.

    По теме: жду добавления примера с массивом итераторов, обновления ссылки на предложенный выше форк (необязательно, но желательно) и, по возможности, разъяснения ситуации с форками проекта - тогда можно будет смело перемещать тему в раздел с проверенными статьями.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  8. #6
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Предложу свой форк standalone библиотеки: https://github.com/Open-GTO/foreach/releases
    Отличается наличием итераторов для актёров и транспорта (в том числе Stream итераторов, которые выключены по умолчанию), поддержкой множественных скриптов (FS + GM), оптимизированным ALS (без использования CallLocalFunction) и отсутствием поддержки npcmodes (для более чистого кода).

    P.S. Не увидел примера использования массивов итераторов, предложу свой: https://github.com/Open-GTO/foreach#...y-of-iterators
    Массив итераторов с игроками в команде:
    PHP код:
    #define MAX_TEAMS 255
    #define MAX_PLAYERS_IN_TEAM MAX_PLAYERS / MAX_TEAMS

    new
        
    Iterator:Team[MAX_TEAMS]<MAX_PLAYERS_IN_TEAM>;

    public 
    OnGameModeInit()
    {
        
    Iter_Init(Team);

        
    #if defined Team_OnGameModeInit
            
    return Team_OnGameModeInit();
        
    #else
            
    return 1;
        
    #endif
    }
    #if defined _ALS_OnGameModeInit
        #undef OnGameModeInit
    #else
        #define _ALS_OnGameModeInit
    #endif

    #define OnGameModeInit Team_OnGameModeInit
    #if defined Team_OnGameModeInit
        
    forward Team_OnGameModeInit();
    #endif



    stock Team_SetPlayerTeam(playeridteamid)
    {
        new 
    current_team GetPlayerTeam(playerid);
        if (
    current_team != NO_TEAM) {
            
    Iter_Remove(Team[current_team], playerid);
        }

        if (
    teamid != NO_TEAM) {
            
    Iter_Add(Team[teamid], playerid);
        }

        return 
    SetPlayerTeam(playeridteamid);
    }
    #if defined _ALS_SetPlayerTeam
        #undef SetPlayerTeam
    #else
        #define _ALS_SetPlayerTeam
    #endif

    #define SetPlayerTeam Team_SetPlayerTeam 
    Использовать так:
    PHP код:
    new scores[MAX_TEAMS];
    for (new 
    teamidteamid MAX_TEAMSteamid++) {
        foreach (new 
    playerid Team[teamid]) {
            
    scores[teamid] += GetPlayerScore(playerid);
        }
    }

    for (new 
    teamidteamid MAX_TEAMSteamid++) {
        
    printf("Team %d: %d"teamidscores[teamid]);

    Этот скрипт суммирует счёт каждой команды и выводит его
    Спасибо за информацию.

    Цитата Сообщение от DeimoS Посмотреть сообщение
    И не хватает примера с трехмерными массивами (взято отсюда, ибо я ленивый):
    PHP код:
    new
        
    Iterator:Iter3[5][8]<10>;
    for (new 
    0!= Iter_InternalSize(Iter3); ++i)
    {
        
    Iter_Init(Iter3[i]);
    }
    Iter_Add(Iter3[3][6], 7); 
    Лишней такая информация не будет
    В автономной версии библиотеки данный способ не работает, ибо она может поддерживать только массив итераторов.

    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    По теме: жду добавления примера с массивом итераторов, обновления ссылки на предложенный выше форк (необязательно, но желательно) и, по возможности, разъяснения ситуации с форками проекта - тогда можно будет смело перемещать тему в раздел с проверенными статьями.
    Обновил.

  9. #7
    Аватар для Alpano
    Пользователь

    Статус
    Оффлайн
    Регистрация
    06.02.2017
    Сообщений
    123
    Репутация:
    16 ±
    Огромное спасибо ziggi за автономную версию) Отказывался от форыча исключительно из-за YSI... +100 к карме)
    MyProject:
    DriftEmpire©

    Ленивые всё делают быстро, чтобы поскорее избавиться от работы.
    И делают качественно, чтобы потом не переделывать.

  10. #8
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от Alpano Посмотреть сообщение
    Огромное спасибо ziggi за автономную версию) Отказывался от форыча исключительно из-за YSI... +100 к карме)
    Это не моя заслуга, я лишь немного обновил существующую автономную версию.

  11. Пользователь сказал cпасибо:
    Alpano (26.03.2017)
  12. #9
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Отредактировал описание отличий foreach и y_iterate в конце темы, подправил грамматику. Полагаю, можно перемещать.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  13. #10
    Аватар для vovandolg
    Пользователь

    Статус
    Оффлайн
    Регистрация
    17.11.2015
    Адрес
    Stavropol
    Сообщений
    1,369
    Репутация:
    113 ±
    Цитата Сообщение от Alpano Посмотреть сообщение
    Огромное спасибо ziggi за автономную версию) Отказывался от форыча исключительно из-за YSI... +100 к карме)
    А причем там YSI, можно и без него обходится foreach'у, или вышла какая то неотъемлемая обнова в данном инклуде?
    [Anticheat]___Invisible Fly Hack
    [Anticheat]____Weapon/Ammo Hack
    [Function]______ResetPlayerWeaponSlot
    [Function]_______FIX_SetPlayerAmmo
    [ServerMod]______TDM | Zombie Apokalypse

 

 
Страница 1 из 4 1 2 3 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •