Sign in to follow this  
Followers 0
Cawfee

Советы по написанию кода. Приведение кода к единому общепринятому стилю

4 posts in this topic

Каждый начинающий разработчик пишет код так, как видит в интернет-ресурсах. Грубо говоря, он привыкает к уже имеющимся шаблонам. Но зачастую код отдельно взятых пользователей лишь вводит в заблуждение о том, что к чему. В программировании существует некий рекомендуемый шаблон, к которому стоит стремиться каждому разработчику. Это позволяет приводить код в общий стиль, что не нарушает читаемость. 

 

Сами советы по написанию кода (рекомендации) будут появляться в данной теме отдельными постами. В создании таких постов может поучаствовать каждый пользователь. 

 

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

Share this post


Link to post
Share on other sites

#1. Названия переменных и функций не стоит писать с помощью транслитерации. Прежде всего такие названия выглядят крайне неприятно. Стоит учесть и то, что функции зачастую называют, например, так: HideRuki. То есть транслитерация и английский вперемешку. Это тоже является ошибкой при написании кода у многих недопрограммистов. К ранее сказанному, старайтесь писать названия переменных на чистом английском, понятным самим англичанам, нежели переводить отдельные части и пытаться составить из них единое название.

 

В английском языке, ровным счетом как и в русском, существуют некие устойчивые выражения. Рассмотрим одно из них - to take a seat. Если переводить каждое слово в отдельности, мы получим взять кресло. Однако, если переводить полный оборот, то увидим иной перевод - присесть. Поэтому важно понять, что перевод в отдельности каждого слова на английском не всегда дает вам адекватный вариант на английском языке.

Share this post


Link to post
Share on other sites

#2. Названия переменных стоит писать с маленькой буквы, первым символом названия не должна быть цифра, не стоит писать название слитно.

Название переменных стоит писать с маленькой буквы.

Переменные должны начинаться с буквы, а не с цифры (это не совет, просто компилятор в принципе не расценит переменную переменной, если оно начинается с цифры). Касаемо разделения написания названия:

Можно, конечно, написать вот так:

new Text: TDLogotipServera;

Но согласитесь, это не очень красиво, гораздо лучше написать в таком виде:

new Text: td_logotype_server;

Здесь мы учли сортировку переменных (о ней ниже), написание с маленькой буквы, разделение слов, название переменных на английском (выше).

Сортировка переменных:

Согласитесь, не красиво, когда у нас переменные в куче, с почти идентичными названиями(особенно если касается единой системы), гораздо лучше использовать "сортировку" переменных, например:

У нас есть переменные одной системы, переменная для таймера, переменная для текстдрава, многие бы написал так:

new SystemTimer;
new Text: SystemTD[5];

Потом гадай, откуда они, для чего они служат (особенно если вы новичок), для этого можно их "отсортировать" - привести в единый вид, вот например, те же переменные, но "отсортированные":

new timer_system;
new Text: td_system[5];

Теперь, чтобы посмотреть все переменные текстдравов, нам достаточно ввести: "td_".

Тип переменных "bool":

Если у нас переменные могут иметь только 2 значения, то лучше использовать тип "bool" например:

new bool: check_belt[MAX_PLAYERS];


if(check_belt[playerid] == false)
{
	действие;
}
else
{
	дествие
}

Данный тип переменных имеет 2 значения: true(истинна) и false(ложь).

Share this post


Link to post
Share on other sites

#3. Старайтесь не иметь скроллинг внизу. 

 

Старайтесь не иметь скроллинга внизу.

Мне например не приятно, когда приходиться скроллинг вправо двигать, чтобы просмотреть какой-либо текст или еще что-то, я просто текст растягиваю на несколько строк, стараюсь сделать это грамотно. Пример длинного текста в разных функциях(SPD, string):

SPD(playerid, 0, DSM, "Длинный диалог", "Здесь у нас будет нас текст, он ооочень длинный, это неудобно, да и некрасиво.", "Закрыть", "");

format(string, sizeof(string), "Здесь у нас будет нас текст, он ооочень длинный, это неудобно, да и некрасиво Nick_Name: %s", name);

Сделаем его короче и понятнее:

SPD(playerid, 0, DSM, 
 "\
	Длинный диалог", "Здесь у нас будет нас текст, он ооочень длинный, это неудобно, да и некрасиво.", "Закрыть", "\
 ");

format(string, sizeof(string), 
 "\
	Здесь у нас будет нас текст, он ооочень длинный, это неудобно, да и некрасиво Nick_Name: %s\
 ", name);

Если текст сам по себе длинный, то можно сделать так:

SPD(playerid, 0, DSM, 
 "\
	Длинный диалог", "Здесь у нас будет нас текст, он ооочень длинный,\
	это неудобно, да и некрасиво.", "Закрыть", "\
 ");

format(string, sizeof(string), 
 "\
	Здесь у нас будет нас текст, он ооочень длинный,\
	это неудобно, да и некрасиво Nick_Name: %s\
 ", name);

Так и текст красивее, и табуляция соблюдается. Я обычно так делаю всегда.

Пример моего кода:

static const fmt_str[] =
 "\
	{FFFFFF}Здравствуйте, {FFFF00}%s!\n{FFFFFF}Вы зашли на сервер {2979FF}"NAME_SERVER"\n\
	\n{FFFFFF}Данный аккаунт зарегистрирован\nДля авторизации аккаунта введите свой пароль:\
 ";
new string[sizeof(fmt_str)-2+MAX_PLAYER_NAME+1];
format(string, sizeof(string), fmt_str, GN(playerid));
SPD(playerid, 3, DSP, "Авторизация на A-RP", string, "Далее", "Выход");

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • Cawfee
      By Cawfee
      В предыдущем уроке я рассказал о том, как пользоваться перехватом функций. Также сказал, что перехваты функций применяются для того, чтобы можно было изменить поведение конкретной функции. Сегодня постараюсь объяснить принцип создания античита и для примера написать для вас античит на деньги.
       
      Как работает античит? Рассмотрим такую ситуацию. При помощи запрещенных программных обеспечений Вы изменяете количество денег у своего игрока. Но спустя несколько секунд (а обычно даже секунду) это количество денег возвращается в прежнее состояние. Можно предположить, что существует какой-то таймер с интервалом, например, в секунду, внутри которого идет проверка: соответствует ли количество денег игрока сейчас тем цифрам, что были во время прежней проверки.
       
      Итак, мы можем получить деньги игрока в данный момент при помощи функции GetPlayerMoney. А с чем нам сверять полученное количество средств? Следует создать новую переменную, в которую уже стоит заносить количество средств, которое должно быть у игрока. Следовательно, нам нужно перехватить функции, связанные с изменением денег, в которых уже производить изменения в значении переменной.
       
      Далее, как я ранее упомянул, следует создать таймер, где уже производить проверку на то, пользуется ли игрок запрещенным программным обеспечением. На этом, в принципе, принцип написания античита завершен. Ровным счетом так же пишутся античиты на здоровье, броню, очки (уровень), телепортацию и многие други. То есть логика везде одинакова.
       
      Начинаем писать античит.
      Мое мнение таково, что античиты следует выносить в отдельные файлы (инклуды). Для этого предлагаю создать в папке "include" новую папку - "anticheats". Внутри новой папки создаем файл "ac_money.inc". Открываем файл.
       
      Прежде всего нам следует задать некое начало нашему файлу, в котором стоит написать проверку на переподключение файла (об этом еще будет урок позже, в данный момент от вас требуется просто скопировать данный мною ниже код):
      #if defined INC_AC_MONEY #endinput #endif #define INC_AC_MONEY Далее мы объявим переменные, в которых будем хранить количество денег игрока (сколько у него должно быть) и ID таймера для игрока, чтобы могли удалять его после того, как игрок отключился.
      static gPlayerMoney[MAX_PLAYERS], // количество денег, которое должно быть у игрока gPlayerTimer[MAX_PLAYERS]; // ID таймера для игрока, в котором будет идти проверка его баланса Теперь приступим к перехватам. Запуск таймера мы начнем в функции OnPlayerConnect (вызывается, когда игрок подключается), а удалять таймер будем в OnPlayerDisconnect.
      public OnPlayerConnect(playerid) { // создаем таймер, где будем проверять игрока на пользование читами gPlayerTimer[playerid] = SetTimerEx("ac_money_OnPlayerSecondTimer", 1000*1, true, "i", playerid); #if defined ac_money_OnPlayerConnect return ac_money_OnPlayerConnect(playerid); #else return 1; #endif } #if defined _ALS_OnPlayerConnect #undef OnPlayerConnect #else #define _ALS_OnPlayerConnect #endif #define OnPlayerConnect ac_money_OnPlayerConnect #if defined ac_money_OnPlayerConnect forward ac_money_OnPlayerConnect(playerid); #endif public OnPlayerDisconnect(playerid, reason) { KillTimer(ac_timerid[playerid]); // удалим таймер для этого игрока #if defined ac_money_OnPlayerDisconnect return ac_money_OnPlayerDisconnect(playerid, reason); #else return 1; #endif } #if defined _ALS_OnPlayerDisconnect #undef OnPlayerDisconnect #else #define _ALS_OnPlayerDisconnect #endif #define OnPlayerDisconnect ac_money_OnPlayerDisconnect #if defined ac_money_OnPlayerDisconnect forward ac_money_OnPlayerDisconnect(playerid); #endif Мы перехватили две функции - OnPlayerConnect и OnPlayerDisconnect, в которых будем создавать и удалять таймер для проверки игрока на пользование читами. Далее мы должны перехватить функции изменения денег (ResetPlayerMoney, GivePlayerMoney), чтобы в них происходило изменение значения переменной, где записано количество денежных средств данного игрока:
      stock ac_money_GivePlayerMoney(playerid, money) // перехватываем функцию GivePlayerMoney { gPlayerMoney[playerid] += money; return GivePlayerMoney(playerid, money); } #if defined _ALS_GivePlayerMoney #undef GivePlayerMoney #else #define _ALS_GivePlayerMoney #endif #define GivePlayerMoney ac_money_GivePlayerMoney stock ac_money_ResetPlayerMoney(playerid) // перехватим функцию ResetPlayerMoney { gPlayerMoney[playerid] = 0; return ResetPlayerMoney(playerid); } #if defined _ALS_ResetPlayerMoney #undef ResetPlayerMoney #else #define _ALS_ResetPlayerMoney #endif #define ResetPlayerMoney ac_money_ResetPlayerMoney Последнее, что мы не сделали - функцию, в которой будем производить проверку: пользуется ли игрок запрещенными программными обеспечениями? Создаем ее (обратите внимание - я создаю функцию с модификатором public потому, что это будет таймер, а все таймеры следует объявлять с модификаторами public).
      forward ac_money_OnPlayerSecond(playerid); public ac_money_OnPlayerSecond(playerid) { if(GetPlayerMoney(playerid) == gPlayerMoney[playerid]) return 1; // все хорошо, деньги "тогда" и сейчас совпадают SendClientMessage(playerid, -1, "Система расценила Ваши действия как действия читера. Количество средств не совпадает."); Kick(playerid); // выкинем игрока с сервера за пользование сторонними ПО return 0; } На этом, вроде бы, все. файл с античитом, который должен был получиться у вас, если Вы следовали согласно данному уроку, я приложу ниже. Спасибо за внимание.
       
      Автор данного урока: @Jawn
      AntiCheat money.inc
    • Cawfee
      By Cawfee
      1. Описание функции.
      Данная функция возвращает транспортное средство на колеса, если оно было перевернуто.
       
      2. Код функции.
      stock FlipVehicle(vehicleid) {     new Float:angle, zAngle;     result = GetVehicleZAngle(vehicleid, zAngle);     if(!result)         return 0;          SetVehicleZAngle(vehicleid, angle);     return 1; }  
      3. Возвращаемые значения.
      Функция FlipVehicle имеет два возвращаемых значения:
      0 - указанный транспорт не существует; 1 - указанный транспорт успешно возвращен на колеса (независимо от того, был ли он перевернут)  
      4. Пример использования функции.
      if(FlipVehicle(vehicleid)) printf("Транспортное средство успешно перевернуто на колеса."); else printf("Транспортное средство не существует на сервере.");  
    • Cawfee
      By Cawfee
      1. Описание макроса.
      Данный макрос проверяет, находится ли число в указанном диапазоне от min до max.
       
      2. Код макроса.
      #if defined IsNumberInRange #undef IsNumberInRange #endif #define IsNumberInRange(%0,%1,%2)\ ((%0-(%1+cellmin)) < (%2-(%1+cellmin)))  
      3. Пример использования.
      new a = 1, b = 2, c = 3; if(IsNumberInRange(b, a, c)) printf("b >= a и b <= c"); else printf("b не принадлежит промежутку [a;c]"); Данный макрос равносилен следующему коду:
      new a = 1, b = 2, c = 3; if(b >= a && b <= c) printf("b принадлежит промежутку [a;c]"); else printf("b не принадлежит промежутку [a;c]");  
       
    • Cawfee
      By Cawfee
      1. Описание функции.
      Данная функция позволяет поменять значения двух переменных местами.
       
      2. Код функции.
      stock swap(&value1, &value2) { #emit lref.s.pri value1 #emit lref.s.alt value2 #emit sref.s.pri value2 #emit sref.s.alt value1 }  
      3. Возвращаемые значения.
      Функция swap не имеет возвращаемых значений.
       
      4. Пример использования.
      new a = 8, b = 10; swap(a, b); // теперь a = 10, b = 8  
    • Cawfee
      By Cawfee
      1. Описание макроса.
      Данный макрос возводит указанное целочисленное или вещественное числа в указанную степень.
       
      2. Код макросов.
      #if defined int_power #undef int_power #endif #define int_power(%0,%1)\ floatround(floatpower(%0,%1)) #if defined float_power #undef float_power #endif #define float_power floatpower  
      3. Пример использования макросов.
      new a, b, power; a = random(100); b = float(random(100)); power = random(3); printf("Число %d в степени %d равно %d.", a, power, int_power(a, power)); printf("Число %f в степени %d равно %f.", b, power, float_power(b, power)); 4. Примечания по содержимому данной темы.
      Разработчиками библиотеки float.inc предусмотрена возможность возводить вещественные (дробные) числа в степень. Соответственно, для этого существует стандартная функция - floatpower. Поэтому использование макроса float_power вовсе необязательно. Он создан исключительно с целью "подгона" стилей функций возведения чисел в степень.