Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Урок Оптимизация циклов MAX_PLAYERS

Статус
В этой теме нельзя размещать новые ответы.

surfer

Дебютант
Здравствуйте!
Сегодня мы рассмотрим оптимизацию циклов такого вида:
PHP:
for(new i=0;i<MAX_PLAYERS;i++)
{ ... }
Ни для кого не секрет, что MAX_PLAYERS определяется в a_samp.inc и равна 500.
Раньше я использовал MAX_PLAYERS вот так:
PHP:
#if defined MAX_PLAYERS
#undef MAX_PLAYERS
#define MAX_PLAYERS 100
#else
#define MAX_PLAYERS 100
#endif
Это конечно давало некоторый прирост, но я пошел еще дальше!
Первой идеей было использовать функцию GetMaxPlayers(), но это никак не помогло бы: на сервере могут быть всего 3 игрока, ид которых 0, 7 и 28, и циклу приходилось бы совершать 28 тактов.

К сожалению, в pawn нельзя создавать динамические массивы, поэтому я придумал использовать что-то вроде псевдодинамического массива для хранения ид подключенных игроков. Создал глобальный массив:
PHP:
new PLIDs[MAX_PLAYERS];
Далее я ввел переменную содержащую количество игроков на сервере:
PHP:
new MaxPlayers = 0;
Очистим весь массив PLIDs при инициализации мода OnGameModInit:
PHP:
for(new i=0;i<sizeof(PLIDs);i++){PLIDs[i] = -1;}
Теперь надо добавить в паблик OnPlayerConnect необходимые операции с глобальными переменными:
PHP:
PLIDs[MaxPlayers] = playerid;
MaxPlayers++;
Все довольно просто - игрок подключается, и его ИД помещается в последнюю свободную ячейку массива PLIDs, ну а переменная MaxPlayers становится на единицу больше.
С пабликом OnPlayerDisconnect все немного сложнее. Игрок выходит, тоесть слот в PLIDs который занимала его ИД надо очистить. Но мне не нужен пустой слот, поэтому я присваиваю ему значение самого последнего слота PLIDs, и вот последний уже очищаю:

PHP:
for(new i=0;i<MaxPlayers;i++)
{
    if(PLIDs[i] == playerid)
    {
        MaxPlayers--;
        PLIDs[i] = PLIDs[MaxPlayers];
        PLIDs[MaxPlayers] = -1;
        break;
    }
}
Все, теперь вы можете оптимизировать массивы.
Пример:
Пусть был массив:

PHP:
for(new i=0;i<MAX_PLAYERS;i++)
{
    if(!IsPlayerConnected(i)){continue;}
    SendClientMessage(i, -1, "Message");
}
После оптимизации:
PHP:
for(new i=0;i<MaxPlayers;i++)
{
    SendClientMessage(PLIDs[i], -1, "Message");
}
Плюсы данного вида:
  • Отсутствуют лишние такты циклов не требуется проверять подключен ли игрок
  • Не требуется проверять подключен ли игрок

Минусы:
  • Меняется порядок ИД игроков при выполнении циклов

На этом у меня все, надеюсь Вам понравился такой вид оптимизации.:ah:
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу