Коллекция функций / макросов

Разбавлю тему моей версией всем известного foreach.
Представленная версия не имеет полного функционала оригинальной версии и была по сути написана с 0 ,так как там творится не ведомая хе... (магия), которую я не осилил. Синтаксис идентичен. Отсутствует поддержка многомерных массивов.
Преимуществом является то, что скорость добавления и удаление переменых на порядок выше.
Quote:

W_foreach Iter_Add & Iter_Remove: 101
foreach Iter_Add & Iter_Remove: 597

Недостатком можно считать: не отсортированный массив (Приведите хоть один пример кому он нужен) и скорость обработки.
Quote:

W_foreach: 39
foreach: 26

Код:
pawn Код:
//==============================================================================
//  Foreach by White_116
#define Iterator:%0<%1> %0[%1]={-1, ...}, w%0[%1+1]={-1, ...}
#define foreach(new%0:%1) for(new %0=sizeof(%1);(%0=w%1[%0]) != -1;)
#define Iter_Add(%1,%0) Itter_AddInternal(%0,%1,w%1,w%1[sizeof(%1)],sizeof(%1))
#define Iter_Remove(%1,%0) Itter_RemoveInternal(%0,%1,w%1,w%1[sizeof(%1)],sizeof(%1))
//==============================================================================
stock Itter_AddInternal(playerid, ds[] ,sd[], &MAX_k, size)
{
    if(-1 < playerid)if(playerid < size)if(MAX_k != playerid)if(ds[playerid] == -1)
    {
        if(MAX_k != -1) ds[MAX_k]=playerid;
        sd[playerid]=MAX_k, MAX_k=playerid;
        return 1;
    }
    return 0;
}
stock Itter_RemoveInternal(playerid, ds[], sd[], &MAX_k, size)
{
    if(-1 < playerid)if(playerid < size)if(playerid != MAX_k)
    {
        if(sd[playerid] != -1)
        {
            sd[ds[sd[playerid]]=ds[playerid]]=sd[playerid];
            return sd[playerid]=ds[playerid]=-1;
        }
        else if(ds[playerid] != -1)return ds[playerid]=sd[ds[playerid]]=-1;
    }
    else if((MAX_k=sd[playerid]) != -1)return ds[MAX_k]=-1; else return -1;
    return 0;
}
//=================                 EOS                     ====================
Пример использования:
pawn Код:
public OnFilterScriptInit()
{
    new Iterator:Some<MAX_PLAYERS>;
    for(new i;i<100;i++)Iter_Add(Some, i*2);
    foreach(new f:Some)printf("foreach: %d",f);
    for(new i;i<100;i++)Iter_Remove(Some, i*2);
    return 1;
}
9.10.2013 - Оптимизировал код.
Reply

В общем, есть функция, которая ищет наивысший свободный слот. Caypen спросил: можно ли такую на pawn реализовать, я ответил, что само-собой) Подобная функция есть в плагине Controllable NPC от 009, но как там она работает - х3. Я предлагаю такой вариант:

pawn Код:
stock FindLastFreeSlot()
{
    new slot = INVALID_PLAYER_ID;
    for(new i = GetMaxPlayers() - 1; i != -1; i--)
    {
        if(IsPlayerConnected(i)) continue;
        slot = i;
        break;
    }
    return slot;
}
Автор: OKStyle

Ну а другой вариант без переменной:

pawn Код:
stock FindLastFreeSlot()
{
    for(new i = GetMaxPlayers() - 1; i > -1; i--)
    {
        if(IsPlayerConnected(i)) continue;
        return i;
    }
    return INVALID_PLAYER_ID; // нет свободных слотов
}
Автор: Caypen
Reply

Кстати тут нашел интересный способ записи циклов, в твоём случае подойдет:
pawn Код:
stock FindLastFreeSlot() {
    for (new i = GetMaxPlayers(); i--;) {
        if (!IsPlayerConnected(i)) return i;
    }
    return INVALID_PLAYER_ID;// нет свободных слотов
}
Reply

Хочу представить Не большую функцию которая позволяет "чертить" пиксельную линию от точки А к точке Б в двумерном пространстве.


pawn Код:
stock raytrace(x0,y0,x1,y1)
{
    new dx=x1-x0, dy=y1-y0;
    if(dx<0)x1=-1, dx=-dx; else x1=1;
    if(dy<0)y1=-1, dy=-dy; else y1=1;
    for(new e=dx-dy, n=dx+dy; n--;)
    {
        if(e > 0) x0+=x1, e-=dy; else y0+=y1, e+=dx;
        //CreateObject(2000, x0, y0, 0.0, 0.0, 0.0, 0.0);//Создадим объект
    }
    return true;
}
Reply

Quote:
Originally Posted by White_116
Посмотреть сообщение
Хочу представить Не большую функцию которая позволяет "чертить" линию от точки А к точке Б в двумерном пространстве.


pawn Код:
stock raytrace(x0,y0,x1,y1)
{
    new dx=x1-x0, dy=y1-y0;
    if(dx<0)x1=-1, dx=-dx; else x1=1;
    if(dy<0)y1=-1, dy=-dy; else y1=1;
    for(new e=dx-dy, n=dx+dy; n--;)
    {
        if(e > 0) x0+=x1, e-=dy; else y0+=y1, e+=dx;
        //CreateObject(2000, x0, y0, 0.0, 0.0, 0.0, 0.0);//Создадим объект
    }
    return true;
}
код актуален только для линий под углом кратным 45.
Reply

Quote:
Originally Posted by Stepashka
Посмотреть сообщение
код актуален только для линий под углом кратным 45.
Хочу вас огорчить, но он для всех углов.
Reply

Ну давай разберем по полочкам:
pawn Код:
stock raytrace(x0,y0,x1,y1)
{
    new dx=x1-x0, dy=y1-y0;//находим проекции по осям
    if(dx<0)x1=-1, dx=-dx; else x1=1;
    if(dy<0)y1=-1, dy=-dy; else y1=1;
    //если проекции отрицательные, мы меняем им знак и записываем в конечные координаты 1 или -1, для чего, с исходными данными выйдет тоже самое!
    for(new e=dx-dy, n=dx+dy; n--;)//находим разницу проекций, зачем, где в геометрии вы такое вычитали?! И спускаемся по их сумме!
    {
        if(e > 0) x0+=x1, e-=dy; else y0+=y1, e+=dx;//если разница больше нуля мы меняем только координату X, если меньше то Y, где логика?!
        //CreateObject(2000, x0, y0, 0.0, 0.0, 0.0, 0.0);//Создадим объект
    }
    return true;
}
при всем этом нам вообще наплевать что координаты должны быть вещественными числами!

Вот как это должно выглядеть:
pawn Код:
stock raytrace(Float:x0, Float:y0, Float:z0, Float:x1, Float:y1, Float:z0, points = 10)
{
    new Float:dx = floatdiv(x1-x0, Float:10),
        Float:dy = floatdiv(y1-y0, Float:10),
        Float:dz = floatdiv(z1-z0, Float:10);
    while(points--) {
        x0 += dx;
        y0 += dy;
        z0 += dz;
        CreateObject(2000, x0, y0, z0, 0.0, 0.0, 0.0);//Создадим объект
    }
}
Reply

Ваша линия будет "вещественная" а моя "пиксельная". Подправил описание.
И в вашем коде ошибка. Float:z0, points = 10)
И ещё одна странность, переменные всегда ровны 0. Не сочтите за криворукость но сервер логирует 0.
PHP код:
while(points--) {
        
printf("%f %f"dx,dy ); 
А вот теперь примените ваши замечания к пиксельной линии.
Reply

Quote:
Originally Posted by White_116
Посмотреть сообщение
Ваша линия будет "вещественная" а моя "пиксельная". Подправил описание.
И в вашем коде ошибка. Float:z0, points = 10)
И ещё одна странность, переменные всегда ровны 0. Не сочтите за криворукость но сервер логирует 0.
PHP код:
while(points--) {
        
printf("%f %f"dx,dy ); 
А вот теперь примените ваши замечания к пиксельной линии.
Все будет работать правильно, если вместо Float:10 использовать float(points)
Reply

Quote:
Originally Posted by White_116
Посмотреть сообщение
Ваша линия будет "вещественная" а моя "пиксельная". Подправил описание.
И в вашем коде ошибка. Float:z0, points = 10)
И ещё одна странность, переменные всегда ровны 0. Не сочтите за криворукость но сервер логирует 0.
PHP код:
while(points--) {
        
printf("%f %f"dx,dy ); 
А вот теперь примените ваши замечания к пиксельной линии.
Копи-паст извините

pawn Код:
stock raytrace(Float:x0, Float:y0, Float:z0, Float:x1, Float:y1, Float:z1, points = 10)
{
    new Float:dx = floatdiv(x1-x0, float(points)),
        Float:dy = floatdiv(y1-y0, float(points)),
        Float:dz = floatdiv(z1-z0, float(points));
    while(points--) {
        x0 += dx;
        y0 += dy;
        z0 += dz;
        CreateObject(2000, x0, y0, z0, 0.0, 0.0, 0.0);//Создадим объект
    }
}
Объясните что вы подразумеваете когда говорите про "пиксельную" линию про координаты в которых вообе нет пикселей?
Reply

Не знаю как вам объяснить грамматно. Откройте пайнт, нарисуйте прямую линию и увеличьте до предела. Вы увидите что там линия рисуется пиксельно.

Если поставить задачу: Определить видимость пути из точки А в точку Б.
MapAndreas + Мой код с этой задачей справится. А вот ваш... он уже не подходит.
Так что по сути, мой и ваш код - это две разные вещи, как круг и кубик.
Reply

Увидел тут одну функцию:

Quote:
Originally Posted by Romanius
Посмотреть сообщение
Функция которой так всем не хватало =) наверно

Эта функция научит компьютер говорить "ПО РУССКИ"

Вы наверно часто сталкивались с проблемой када говорило "На сервере 21 игроков"

А эта функция вернет один из предложенных ей вариантов

Код
Код:
stock GetNeededWord(number,word1[],word2[],word3[]) // by Romanius
{
	new ostatok = number % 100;
	new out[50];
	
	if((ostatok > 10) && (ostatok < 20)) strcat(out,word3);
	else
	{
	  switch(ostatok % 10)
	  {
	    case 0: strcat(out,word3);
	    case 1: strcat(out,word1);
			case 2..4: strcat(out,word2);
			case 5..9: strcat(out,word3);
			default: strcat(out,word1);
	  }
	}
	return out;
}
Вот моё предложение:
PHP код:
stock CNum(num,st1[20],st2[20],st3[20])
{
    new 
s1[20]; valstr(s1,num);
    new 
strlen(s1)+1;
    
    if(
s1[i] == '1') return st1;
    else if(
s1[i] == '2') return st2;
    else if(
s1[i] == '3') return st2;
    else if(
s1[i] == '4') return st2;
    else return 
st3;

Или:
PHP код:
stock CNum(numst1[], st2[], st3[])
{
    new 
s1[20],s2[20]; valstr(s1,num);
    new 
strlen(s1)+1;
    
    switch(
s1[i])
    {
        case 
'1':      strcat(s2,st1);
        case 
'2'..'4'strcat(s2,st2);
        default:       
strcat(s2,st3);
    }
    return 
s2;

Reply

pawn Код:
#define abs(%0) floatround(floatabs(Float:(%0))) // Stepashka
stock pluralForm(n, form1[], form2[], form5[], output[])
{
    n = abs(n) % 100;
    new n1 = n % 10;
    if (10 < n < 20) return strcat(output, form5);
    if (1 < n1 < 5) return strcat(output, form2);
    if (n1 == 1) return strcat(output, form1);
    return strcat(output, form5);
}
Reply

последний аргумент size зачем? если он не используется в ф-ии.
Reply

Quote:
Originally Posted by Diman777
Посмотреть сообщение
последний аргумент size зачем? если он не используется в ф-ии.
Забыл убрать, исправил. )
Reply

PHP код:
#define abs(%0) ((%0<0)?(-%0):(%0))
abs(n) % 100
PHP код:
100;
floatabs(n); 
Reply

Quote:
Originally Posted by Gameyer
Посмотреть сообщение
PHP код:
#define abs(%0) ((%0<0)?(-%0):(%0))
abs(n) % 100
PHP код:
100;
floatabs(n); 
Что это?
pawn Код:
#define abs(%0) floatround(floatabs(Float:(%0)))
Reply

Это значит то, что в самп есть своя функция, которая берет число по модулю.
Reply

Quote:
Originally Posted by Gameyer
Посмотреть сообщение
Это значит то, что в самп есть своя функция, которая берет число по модулю.
Не так понял. Пишите хоть комментарии.
Reply

Рандомное значение HEX
PHP Code:
stock RandHex()
{
    new 
random(239)+16;
    new 
random(239)+16;
    new 
random(239)+16;
    return (
r*16777216)+(g*65536)+(b*256)+0xFF;
}
// или можно в define
#define RandHex() ((random(239)+16)*16777216)+((random(239)+16)*65536)+((random(239)+16)*256)+0xFF 
Пример использования
PHP Code:
SendClientMessage(playeridRandHex(),"Text Color");
SetPlayerColor(playeridRandHex()); 
Автор: SoNik))
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)