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

    Статус
    Оффлайн
    Регистрация
    06.02.2017
    Сообщений
    123
    Репутация:
    16 ±
    Цитата Сообщение от vovandolg Посмотреть сообщение
    А причем там YSI, можно и без него обходится foreach'у, или вышла какая то неотъемлемая обнова в данном инклуде?
    До того как встретил эту статью, не знал что есть форыч через YSI.
    MyProject:
    DriftEmpire©

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

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

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

  3. #13
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

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

  4. Пользователь сказал cпасибо:
    Alpano (26.03.2017)
  5. #14
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    Пример №3
    Создадим скрипт, суммирующий счёт каждой команды. В нём нам необходимо использовать массива итераторов.
    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]);

    Мне кажется или этот код не совсем рабочий? По крайней мере в том виде, в котором он имеется сейчас.
    Возможно, в первоисточнике, откуда взят этот пример, формула в MAX_PLAYERS_IN_TEAM не такая странная для макроса, что указывается в качестве размера итератора, но сейчас она немножко бредовая

    Да и вообще смысла от этого макроса нет, ибо нормально итератор будет работать только в таком виде:
    PHP код:
    new
        
    Iterator:Team[MAX_TEAMS]<MAX_PLAYERS>; 
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Мне кажется или этот код не совсем рабочий? По крайней мере в том виде, в котором он имеется сейчас.
    Возможно, в первоисточнике, откуда взят этот пример, формула в MAX_PLAYERS_IN_TEAM не такая странная для макроса, что указывается в качестве размера итератора, но сейчас она немножко бредовая

    Да и вообще смысла от этого макроса нет, ибо нормально итератор будет работать только в таком виде:
    PHP код:
    new
        
    Iterator:Team[MAX_TEAMS]<MAX_PLAYERS>; 
    Что не так то? Код ведь компилируется и прекрасно работает. А подсчёт MAX_PLAYERS_IN_TEAM сделан таким образом, чтобы на сервере одновременно могло быть MAX_TEAMS команд. Если захочется больше игроков в команде - то нужно уменьшить количество команд, вполне логично.

  7. #16
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Что не так то? Код ведь компилируется и прекрасно работает. А подсчёт MAX_PLAYERS_IN_TEAM сделан таким образом, чтобы на сервере одновременно могло быть MAX_TEAMS команд. Если захочется больше игроков в команде - то нужно уменьшить количество команд, вполне логично.
    Ну представим, что MAX_PLAYERS не изменялось и равно 1000. Следовательно, в макросе MAX_PLAYERS_IN_TEAM будет записано "1000/255", что равно, примерно, 4, хотя компилятор округлит до 3-х, скорее всего (разницы особой нет). Следовательно, размер итератора тоже будет равен трём:
    PHP код:
    new 
        
    Iterator:Team[MAX_TEAMS]<3>; 
    Что означает, что в него нельзя будет записать число больше двух (ибо алгоритм таков).
    То бишь, в этих итераторах будут записаны исключительно игроки с 0 по 2-ой ID и никто более.
    PHP код:
    Iter_Add(Team[0], 4);//Уже не запишет 
    Не думаю, что изначально именно такая была задумка.
    Последний раз редактировалось DeimoS; 27.04.2017 в 00:17.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Ну представим, что MAX_PLAYERS не изменялось и равно 1000. Следовательно, в макросе MAX_PLAYERS_IN_TEAM будет записано "1000/255", что равно, примерно, 4, хотя компилятор округлит до 3-х, скорее всего (разницы особой нет). Следовательно, размер итератора тоже будет равен трём:
    PHP код:
    new 
        
    Iterator:Team[MAX_TEAMS]<3>; 
    Что означает, что в него нельзя будет записать число больше двух (ибо алгоритм таков).
    То бишь, в этих итераторах будут записаны исключительно игроки с 0 по 2-ой ID и никто более.
    PHP код:
    Iter_Add(Team[0], 4);//Уже не запишет 
    Не думаю, что изначально именно такая была задумка.
    Нет, это означает, что в итератор будет записано 3 игрока.
    PHP код:
    Iter_Add(Team[0], 4); // запишет
    Iter_Add(Team[0], 999); // запишет
    Iter_Add(Team[0], cellmax); // запишет
    Iter_Add(Team[0], 1); // не запишет 

    UPD
    А нет, всё так, мой косяк. Что-то я попутал...
    Последний раз редактировалось ziggi; 27.04.2017 в 01:09.

  9. #18
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Нет, это означает, что в итератор будет записано 3 игрока.
    PHP код:
    Iter_Add(Team[0], 4); // запишет
    Iter_Add(Team[0], 999); // запишет
    Iter_Add(Team[0], cellmax); // запишет
    Iter_Add(Team[0], 1); // не запишет 

    UPD
    А нет, всё так, мой косяк. Что-то я попутал...
    Сам когда-то погорел на этом, долго не понимая почему не записывает в итератор мои значения :) Пока наконец не переборол упрямство вперемешку с желанием разобраться самостоятельно и не нашёл статью на sa-mp.com об итераторах, которую выше кидал.

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

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

    Steve Pavlina

  10. #19
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Совсем забыл изначальную цель, ради которой я заглядывал в тему пару дней назад :D

    Я бы ещё отдельно акцентировал внимание на том, что итераторы станут хорошей заменой всех массивов, значение которых впоследствии проверяется в цикле (особенно массивов, значение которых бывает равно только нулю и единице и массивов MAX_PLAYERS). У итераторов в этом плане сразу несколько плюсов, при том, что и возможности массива не теряются: и возможность "пробежаться" по нужным данными без дополнительных проверок, и узнать количество данных без дополнительных переменных или подсчёта в цикле (Iter_Count), не говоря уже о возможности получения случайного члена этих данных (Iter_Random).
    А то для многих интеграция foreach в SA-MP заканчивается чем-то подобным:
    PHP код:
    foreach(new iPlayer)
    {
        if(
    IsPlayerAdmin)
        
    //...

    хотя разумнее создать итератор
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

  11. #20
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Кстати говоря, вот это ограничение:

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

    Нужно создать обыкновенный массив с нужным нам количеством ячеек и итератор с таким же количеством.
    Итератор не будет хранить каких-либо значений, кроме занятых индексов в основном массиве.
    Проще показать на примере кода:

    PHP код:
    new test_array[MAX_PLAYERS],// Наш массив, который будет хранить нужные нам значения (ограничено лишь cellmin/cellmax)
        
    Iterator:TestIter<sizeof(test_array)>; // Итератор с тем же числом ячеек, который будет хранить ID занятых ячеек в основном массиве (меньше 0 или больше MAX_PLAYERS-1 не записать)


    public OnGameModeInit() 

        new 
    idx,
            
    i,
            
    rand;

        for(
    030i++)// В этом цикле мы заносим данные в первые 30 ячеек массива
        
    {
            
    idx Iter_Free(TestIter);// Для наглядности показываю как можно легко найти свободную ячейку в массиве
            
    test_array[idx] = INVALID_PLAYER_ID;// Собственно, сама запись значения
            
    Iter_Add(TestIteridx);// И указание того, что ячейка занята
        
    }

        for(
    010i++)// Теперь "удалим" 10 рандомных значений из массива
        
    {
            
    rand random(30);
            
    test_array[rand] = 0;// Обнулили ячейку (хотя на самом деле это не обязательно делать. Важно лишь удалить ячейку из итератора. Я прописал обнуление, дабы в последнем цикле наглядно показать какие ячейки будут выбраны великим псевдорандомом)
            
    Iter_Remove(TestIterrand);// И удалили ячейку из итератора, указав, что она освободилась (ВАЖНО!)
        
    }

        print(
    "\n\nforeach:");// Теперь выведем в консоль значения массива при помощи foreach И обычного цикла, дабы сравнить данные
        
    foreach(new tTestIter)
        {
            
    printf("%i) %i"ttest_array[t]);
        }
        print(
    "\nfor:");
        for(
    030i++)
        {
            
    printf("%i) %i"itest_array[i]);
        }
        print(
    "\n\n");

        return 
    1;

     Результат
    PHP код:
    foreach:
    065535
    1
    65535
    2
    65535
    4
    65535
    5
    65535
    7
    65535
    8
    65535
    9
    65535
    10
    65535
    11
    65535
    12
    65535
    13
    65535
    14
    65535
    16
    65535
    17
    65535
    20
    65535
    22
    65535
    23
    65535
    25
    65535
    26
    65535
    28
    65535
    29
    65535

    for:
    065535
    1
    65535
    2
    65535
    3
    0
    4
    65535
    5
    65535
    6
    0
    7
    65535
    8
    65535
    9
    65535
    10
    65535
    11
    65535
    12
    65535
    13
    65535
    14
    65535
    15
    0
    16
    65535
    17
    65535
    18
    0
    19
    0
    20
    65535
    21
    0
    22
    65535
    23
    65535
    24
    0
    25
    65535
    26
    65535
    27
    0
    28
    65535
    29
    65535 
    Как видно, все ячейки, которым "сбросили" значение, не были выведены в foreach, а выведены лишь ячейки с нашим значением





    Так, собственно, можно реализовать систему, что дана в примере
    PHP код:
    #define MAX_TEAMS                255
    #define MAX_PLAYERS_IN_TEAM        MAX_PLAYERS / MAX_TEAMS

    new    players_in_team[MAX_TEAMS][MAX_PLAYERS_IN_TEAM],
        
    Iterator:Team[sizeof(players_in_team)]<sizeof(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),
            
    idx ITER_NONE;
        if(
    current_team != NO_TEAM
        {
            foreach(new 
    iTeam[current_team])
            {
                if(
    players_in_team[current_team][idx] == playerid)
                {
                    
    idx i;
                    break;
                }
            }
            
    Iter_Remove(Team[current_team], idx);
        }

        if(
    teamid != NO_TEAM
        {
            
    idx Iter_Free(Team[current_team]);
            if(
    idx == ITER_NONE)// Если в команде нет места - возвращаем 0.
                
    return 0;
            
    players_in_team[current_team][idx] = playerid;
            
    Iter_Add(Team[teamid], idx);
        }

        return 
    SetPlayerTeam(playeridteamid), 1;// Иначе - 1
    }
    #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 
    idx Team[teamid]) 
        {
            
    scores[teamid] += GetPlayerScore(players_in_team[teamid][idx]);
        }
    }

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

    Собственно и остальные преимущества foreach сохраняются: при помощи Iter_Count можно узнать количество значений, занесённых в основной массив, при помощи Iter_Contains можно узнать, занята ли определённая ячейка и т.п.

    P.S. Писал в браузере и на работоспособность не проверял. Но общий алгоритм прописан
    Последний раз редактировалось DeimoS; 08.05.2017 в 05:19.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

 

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

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

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

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

Ваши права

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