Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 9 из 9
  1. #1
    Аватар для DmitriyVasilev
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.01.2019
    Сообщений
    86
    Репутация:
    0 ±

    Обычный подсчет или автоподсчет ячеек

    Здравствуйте, можно узнать?
    можно ли везде использовать автоподсчёт от Corteza а когда лучше будет просто использовать ручной подсчет.
    И объясните каким образом тут подсчитаны ячейки, спасибо огромное!
    1. new string[29+(-2+10)+1];
    2. format(string, sizeof string, "С 01.01.1970 прошло %d секунд", gettime());

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

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Можно, конечно, но во многих случаях код подсчёта может занимать гораздо больше места, чем сама функция, в которой будет выводиться сообщение. То бишь, в определённых случаях гораздо практичнее подсчитать вручную, ибо код будет более компактным и опрятным. Но если тебя устраивает "раздутость" с автоподсчётом - можешь пользоваться им. Хуже в плане производительности от этого не будет.

    Цитата Сообщение от DmitriyVasilev Посмотреть сообщение
    И объясните каким образом тут подсчитаны ячейки, спасибо огромное!
    1. new string[29+(-2+10)+1];
    2. format(string, sizeof string, "С 01.01.1970 прошло %d секунд", gettime());
    "29" - это число символов в изначальной строке -> "С 01.01.1970 прошло %d секунд"
    "-2" - это учёт заполнителя "%d" (заполнители при форматировании заменяются на данные, которые передаются в строку (в данном случае это значение gettime) => нам не нужно учитывать эти 2 символа при подсчёте)
    "10" - это максимальное количество символов, которые могут быть возвращены функцией "gettime()"
      Открыть/закрыть
    Функция возвращает число. Максимально возможное число, которое можно хранить в 32-разрядной системе - "2147483647". В данном числе как раз 10 символов. Отсюда и число "10".
    Если бы ты, например, выводил ник игрока в строку, то указывать следовало бы "MAX_PLAYER_NAME" иди "24" (но лучше указать именно макрос, дабы если в будущем максимальная длина ника изменится разработчиком, то не пришлось бы изменять вручную все формулы). Ну а если, например, ID игрока, то указать следует 3 символа (максимальный ID игрока - 999). То бишь, чтоб подсчитать размер входящих в строку данных, тебе нужно представить эти данные в максимально возможном их виде, а после подсчитать количество символов для хранения этого "максимального" варианта.

    "+1" в конце - это учёт нуль-символа

    Вообще формулу можно составлять по всякому. Я, например, предпочитаю не прописывать явно вычет заполнителя (те самые "-2"), а учитывать их сразу при подсчёте длины строки. То бишь, я бы написал сразу "27" вместо "29" и формула у меня выглядела бы так
    PHP код:
    new string[27+10+1]; 
    Не принципиально как ты будешь составлять формулы (хотя предпочтительнее делать это по какому-то общему шаблону, чтоб в будущем, если появится нужда изменить строку и пересчитать её длину, это можно было сделать с лёгкостью, изменив лишь часть формулы, а не пересчитывая её по новой). При желании, можешь вообще не составлять формулу, а сразу писать готовое число (но тогда, в случае изменения строки, его придётся пересчитывать по новой), а-ля:
    PHP код:
    new string[38];//27+10+1 = 38 
    - - - Добавлено - - -

    Цитата Сообщение от DeimoS Посмотреть сообщение
    Можно, конечно, но во многих случаях код подсчёта может занимать гораздо больше места, чем сама функция, в которой будет выводиться сообщение.
    Например, так команда выглядела с автопосчётом:
      Открыть/закрыть
    1. CMD:getcord(playerid, params[]) // by Daniel_Cortez
    2. {
    3. if(PlayerInfo[playerid][pAdmin] < 1)
    4. return 1;
    5. static const
    6. fmt_str0[] = "Координаты: X = %8.2f, Y = %8.2f, Z = %8.2f",
    7. fmt_str1[] = "Угол поворота: %8.2f°",
    8. fmt_str2[] = "Интерьер: %d, вирт. мир: %d";
    9. const
    10. size0 = sizeof(fmt_str0)+(-5+11)*3,
    11. size1 = sizeof(fmt_str1)-5+11,
    12. size2 = sizeof(fmt_str2)+(-2+11)*2;
    13. #if size0>size1
    14. #define size size0
    15. #else
    16. #define size size1
    17. #endif
    18. #if size2>size
    19. #undef size
    20. #define size size2
    21. #endif
    22. new string[size];
    23. #undef size
    24. {
    25. new Float:x, Float:y, Float:z;
    26. GetPlayerPos(playerid, x, y, z);
    27. format(string, sizeof(string), fmt_str0, x, y, z);
    28. }
    29. SendClientMessage(playerid, -1, string);
    30. {
    31. new Float:f;
    32. GetPlayerFacingAngle(playerid, f);
    33. format(string, sizeof(string), fmt_str1, f);
    34. }
    35. SendClientMessage(playerid, -1, string);
    36. new
    37. i = GetPlayerInterior(playerid),
    38. w = GetPlayerVirtualWorld(playerid);
    39. format(string, sizeof(string), fmt_str2, i, w);
    40. return SendClientMessage(playerid, -1, string);
    41. }


    А так она выглядит сейчас:
      Открыть/закрыть
    1. CMD:getpos(playerid, params[]) // by Daniel_Cortez \ pro-pawn.ru
    2. {
    3. // Проверка на админа (если нужно, замените на свою).
    4. if (PlayerInfo[playerid][pAdmin] < 1)
    5. return 1;
    6.  
    7. new string[62];
    8. static Float:x, Float:y, Float:z, Float:f, i, w;
    9. GetPlayerPos(playerid, x, y, z);
    10. format(string, sizeof(string), "Координаты: X = %8.2f, Y = %8.2f, Z = %8.2f", x, y, z);
    11. SendClientMessage(playerid, -1, string);
    12.  
    13. GetPlayerFacingAngle(playerid, f);
    14. format(string, sizeof(string), "Угол поворота: %8.2f°", f);
    15. SendClientMessage(playerid, -1, string);
    16.  
    17. i = GetPlayerInterior(playerid);
    18. w = GetPlayerVirtualWorld(playerid);
    19. format(string, sizeof(string), "Интерьер: %d, вирт. мир: %d", i, w);
    20. return SendClientMessage(playerid, -1, string);
    21. }


    Там, конечно, помимо отказа от автоподсчёта, есть ещё некоторые изменения, но, в целом, видно, что в данном случае автоподсчёт только "раздувал" код команды. В итоге, если такой автоподсчёт использовать повсеместно, что приличный процент кода будет занимать только этот самый автоподсчёт. А чем больше кода, тем труднее его поддерживать, ибо, как минимум, приходится дольше искать тот или иной участок кода. Вот тут я ещё несколько "проблемных мест", по моему мнению, описывал касаемо автоподсчёта.

    В целом, лично я так и не нашёл применение для автоподсчёта. Для меня гораздо практичнее и быстрее использовать функционал редактора кода, который подсчитывает выделенный текст
      Открыть/закрыть

    дабы получившееся значение в дальнейшем использовать при составлении формулы (как показал в предыдущем сообщении). Но это ни в коем случае не призыв к отказу от автоподсчёта. Используй то, что тебе удобнее. Главное научись правильно составлять формулу, ибо иначе от этого может быть больше проблем, чем пользы.
    Последний раз редактировалось DeimoS; 03.03.2019 в 13:24.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

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

    Статус
    Оффлайн
    Регистрация
    01.01.2019
    Сообщений
    86
    Репутация:
    0 ±
    а куда ответ ваш делся

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

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Эмм, он на месте. Вот:
      Открыть/закрыть
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Можно, конечно, но во многих случаях код подсчёта может занимать гораздо больше места, чем сама функция, в которой будет выводиться сообщение. То бишь, в определённых случаях гораздо практичнее подсчитать вручную, ибо код будет более компактным и опрятным. Но если тебя устраивает "раздутость" с автоподсчётом - можешь пользоваться им. Хуже в плане производительности от этого не будет.

    Цитата Сообщение от DmitriyVasilev Посмотреть сообщение
    И объясните каким образом тут подсчитаны ячейки, спасибо огромное!
    1. new string[29+(-2+10)+1];
    2. format(string, sizeof string, "С 01.01.1970 прошло %d секунд", gettime());
    "29" - это число символов в изначальной строке -> "С 01.01.1970 прошло %d секунд"
    "-2" - это учёт заполнителя "%d" (заполнители при форматировании заменяются на данные, которые передаются в строку (в данном случае это значение gettime) => нам не нужно учитывать эти 2 символа при подсчёте)
    "10" - это максимальное количество символов, которые могут быть возвращены функцией "gettime()"
      Открыть/закрыть
    Функция возвращает число. Максимально возможное число, которое можно хранить в 32-разрядной системе - "2147483647". В данном числе как раз 10 символов. Отсюда и число "10".
    Если бы ты, например, выводил ник игрока в строку, то указывать следовало бы "MAX_PLAYER_NAME" иди "24" (но лучше указать именно макрос, дабы если в будущем максимальная длина ника изменится разработчиком, то не пришлось бы изменять вручную все формулы). Ну а если, например, ID игрока, то указать следует 3 символа (максимальный ID игрока - 999). То бишь, чтоб подсчитать размер входящих в строку данных, тебе нужно представить эти данные в максимально возможном их виде, а после подсчитать количество символов для хранения этого "максимального" варианта.

    "+1" в конце - это учёт нуль-символа

    Вообще формулу можно составлять по всякому. Я, например, предпочитаю не прописывать явно вычет заполнителя (те самые "-2"), а учитывать их сразу при подсчёте длины строки. То бишь, я бы написал сразу "27" вместо "29" и формула у меня выглядела бы так
    PHP код:
    new string[27+10+1]; 
    Не принципиально как ты будешь составлять формулы (хотя предпочтительнее делать это по какому-то общему шаблону, чтоб в будущем, если появится нужда изменить строку и пересчитать её длину, это можно было сделать с лёгкостью, изменив лишь часть формулы, а не пересчитывая её по новой). При желании, можешь вообще не составлять формулу, а сразу писать готовое число (но тогда, в случае изменения строки, его придётся пересчитывать по новой), а-ля:
    PHP код:
    new string[38];//27+10+1 = 38 
    - - - Добавлено - - -

    Цитата Сообщение от DeimoS Посмотреть сообщение
    Можно, конечно, но во многих случаях код подсчёта может занимать гораздо больше места, чем сама функция, в которой будет выводиться сообщение.
    Например, так команда выглядела с автопосчётом:
      Открыть/закрыть
    1. CMD:getcord(playerid, params[]) // by Daniel_Cortez
    2. {
    3. if(PlayerInfo[playerid][pAdmin] < 1)
    4. return 1;
    5. static const
    6. fmt_str0[] = "Координаты: X = %8.2f, Y = %8.2f, Z = %8.2f",
    7. fmt_str1[] = "Угол поворота: %8.2f°",
    8. fmt_str2[] = "Интерьер: %d, вирт. мир: %d";
    9. const
    10. size0 = sizeof(fmt_str0)+(-5+11)*3,
    11. size1 = sizeof(fmt_str1)-5+11,
    12. size2 = sizeof(fmt_str2)+(-2+11)*2;
    13. #if size0>size1
    14. #define size size0
    15. #else
    16. #define size size1
    17. #endif
    18. #if size2>size
    19. #undef size
    20. #define size size2
    21. #endif
    22. new string[size];
    23. #undef size
    24. {
    25. new Float:x, Float:y, Float:z;
    26. GetPlayerPos(playerid, x, y, z);
    27. format(string, sizeof(string), fmt_str0, x, y, z);
    28. }
    29. SendClientMessage(playerid, -1, string);
    30. {
    31. new Float:f;
    32. GetPlayerFacingAngle(playerid, f);
    33. format(string, sizeof(string), fmt_str1, f);
    34. }
    35. SendClientMessage(playerid, -1, string);
    36. new
    37. i = GetPlayerInterior(playerid),
    38. w = GetPlayerVirtualWorld(playerid);
    39. format(string, sizeof(string), fmt_str2, i, w);
    40. return SendClientMessage(playerid, -1, string);
    41. }


    А так она выглядит сейчас:
      Открыть/закрыть
    1. CMD:getpos(playerid, params[]) // by Daniel_Cortez \ pro-pawn.ru
    2. {
    3. // Проверка на админа (если нужно, замените на свою).
    4. if (PlayerInfo[playerid][pAdmin] < 1)
    5. return 1;
    6.  
    7. new string[62];
    8. static Float:x, Float:y, Float:z, Float:f, i, w;
    9. GetPlayerPos(playerid, x, y, z);
    10. format(string, sizeof(string), "Координаты: X = %8.2f, Y = %8.2f, Z = %8.2f", x, y, z);
    11. SendClientMessage(playerid, -1, string);
    12.  
    13. GetPlayerFacingAngle(playerid, f);
    14. format(string, sizeof(string), "Угол поворота: %8.2f°", f);
    15. SendClientMessage(playerid, -1, string);
    16.  
    17. i = GetPlayerInterior(playerid);
    18. w = GetPlayerVirtualWorld(playerid);
    19. format(string, sizeof(string), "Интерьер: %d, вирт. мир: %d", i, w);
    20. return SendClientMessage(playerid, -1, string);
    21. }


    Там, конечно, помимо отказа от автоподсчёта, есть ещё некоторые изменения, но, в целом, видно, что в данном случае автоподсчёт только "раздувал" код команды. В итоге, если такой автоподсчёт использовать повсеместно, что приличный процент кода будет занимать только этот самый автоподсчёт. А чем больше кода, тем труднее его поддерживать, ибо, как минимум, приходится дольше искать тот или иной участок кода. Вот тут я ещё несколько "проблемных мест", по моему мнению, описывал касаемо автоподсчёта.

    В целом, лично я так и не нашёл применение для автоподсчёта. Для меня гораздо практичнее и быстрее использовать функционал редактора кода, который подсчитывает выделенный текст
      Открыть/закрыть

    дабы получившееся значение в дальнейшем использовать при составлении формулы (как показал в предыдущем сообщении). Но это ни в коем случае не призыв к отказу от автоподсчёта. Используй то, что тебе удобнее. Главное научись правильно составлять формулу, ибо иначе от этого может быть больше проблем, чем пользы.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

  5. #5
    Аватар для DmitriyVasilev
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.01.2019
    Сообщений
    86
    Репутация:
    0 ±
    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 128974801 bytes) in /var/www/u0253307/data/www/pro-pawn.ru/includes/functions_threadedmode.php on line 23
    мне пишет когда нажимаю на ваш ответ из раздела форум, а здесь только мои сообщения

  6. #6
    Аватар для DmitriyVasilev
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.01.2019
    Сообщений
    86
    Репутация:
    0 ±
    я правильно сосчитал?
    1. new bandprotect[24], bandattack[24];
    2. switch(GZInfo[i][gFrakVlad])
    3. {
    4. case 12: bandprotect="Ballas";
    5. case 13: bandprotect="Vagos";
    6. case 15: bandprotect="Grove";
    7. case 17: bandprotect="Aztecas";
    8. case 18: bandprotect="Rifa";
    9. }
    10. switch(User[playerid][pMember])
    11. {
    12. case 12: bandattack="Ballas";
    13. case 13: bandattack="Vagos";
    14. case 15: bandattack="Grove";
    15. case 17: bandattack="Aztecas";
    16. case 18: bandattack="Rifa";
    17. }
    18. new fmt_str[(27 - 4) + ( 48 + 1)];
    19. format(fmt_str,sizeof(fmt_str),"Банда %s напала на банду %s", bandattack, bandprotect);
    20. и
    21. if(IsAGunsCar(newcar))
    22. {
    23. new fmt_str[16 + ( -2 + 11 ) + 1];
    24. format(fmt_str, sizeof(fmt_str), "Оружия: %i/10000", MatHaul[newcar-gunscar[0]][mLoad],MatHaul[newcar-gunscar[0]][mCapasity]);
    25. SCM(playerid, TEAM_GROVE_COLOR, fmt_str);
    26. SCM(playerid, -1, !"(( Для загрузки/разгрузки Оружия Введите: /carm ))");
    27. }
    Последний раз редактировалось DmitriyVasilev; 03.03.2019 в 16:50.

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

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Скобки расставлены довольно странно, но в остальном - да, правильно.
    Обычно скобками отделяют вычисление для разных данных. В твоём случае было бы как-то так:
    PHP код:
    new fmt_str[27+(-2+sizeof(bandprotect))+(-2+sizeof(bandattack))+1]; 
    То бишь, отдельно размер строки без учёта входящих данных и отдельно вычисление для каждого заполнителя. В таком случае, если ты, например, решишь убрать отображение "bandattack", то тебе достаточно просто удалить первую скобку и не нужно будет ничего пересчитывать. В этом весь смысл такого составления формул :)
    Ну и стоит нормально подсчитать размер для bandprotect/bandattack.


    Хотя вообще в твоём случае лучше сделать так:
    1. static const band_list[][] =// Зарезервируем переменную сразу в сегменте данных, дабы при каждом вызове кода не заниматься извлечением данных в стэк
    2. {
    3. "Ballas", // 12 ID | 0 ячейка
    4. "Vagos", // 13 ID | 1 ячейка
    5. "Grove", // 15 ID | 2 ячейка
    6. "Aztecas", // 17 ID | 3 ячейка
    7. "Rifa" // 18 ID | 4 ячейка
    8. };
    9.  
    10. //Далее сопоставим ID фракций номеру ячеек в массиве.
    11. new protect_idx;
    12. switch(GZInfo[i][gFrakVlad])
    13. {
    14. case 12: protect_idx = 0;
    15. case 13: protect_idx = 1;
    16. case 15: protect_idx = 2;
    17. case 17: protect_idx = 3;
    18. case 18: protect_idx = 4;
    19. }
    20.  
    21. new attack_idx;
    22. switch(User[playerid][pMember])
    23. {
    24. case 12: attack_idx = 0;
    25. case 13: attack_idx = 1;
    26. case 15: attack_idx = 2;
    27. case 17: attack_idx = 3;
    28. case 18: attack_idx = 4;
    29. }
    30.  
    31. new fmt_str[27+ (-2+sizeof(band_list[])) + (-2+sizeof(band_list[])) +1];
    32. format(fmt_str,sizeof(fmt_str),"Банда %s напала на банду %s", band_list[attack_idx], band_list[protect_idx]);// Получим нназвание банд из массива согласно полученному номеру ячейки
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

  8. #8
    Аватар для DmitriyVasilev
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.01.2019
    Сообщений
    86
    Репутация:
    0 ±
    warning 224: indeterminate array size in "sizeof" expression (symbol "")
    это в new fmt_str[27+ (-2+sizeof(band_list[])) + (-2+sizeof(band_list[])) +1];

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

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

    1. static const band_list[5][8] =// Зарезервируем переменную сразу в сегменте данных, дабы при каждом вызове кода не заниматься извлечением данных в стэк
    2. {
    3. "Ballas", // 12 ID | 0 ячейка
    4. "Vagos", // 13 ID | 1 ячейка
    5. "Grove", // 15 ID | 2 ячейка
    6. "Aztecas", // 17 ID | 3 ячейка
    7. "Rifa" // 18 ID | 4 ячейка
    8. };
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

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

    Steve Pavlina

 

 

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

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

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

Ваши права

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