Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 12
  1. #1
    Аватар для SteveStage
    Пользователь

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±

    Разные вариации одного и того же слова

    Вот например есть система бана, и при бане выводит сообщение:

    Steve_Stage забанил игрока Mario_Otto на 1 дней по причине: снят

    Но ведь мы не говорим : 1 дней.
    Как можно сделать несколько вариаций слова "день", в зависимости от дней бана?

    Я знаю, что можно создать двумерный массив, и написать туда "день", "дня", "дня", "дня", "дней" и т.д., но это долго и неэффективно.

    Есть ли способ сделать несколько вариаций одного слова в зависимости от значения дней бана, и чтобы это было читабельно и эффективно?

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

    Статус
    Оффлайн
    Регистрация
    20.01.2018
    Сообщений
    52
    Репутация:
    7 ±
    PHP код:
    new _macros_new_num;
    #define PluralToText(%0,%1,%2,%3) \
        
    ((_macros_new_num = ((%100) >= 20 ? (%10) : %0)) == ? (%1) : (<= _macros_new_num <= ? (%2) : (%3)))
    //"новое уведомление"(1), "новых уведомления"(2-4), "новых уведомлений" 

    //
    PluralToText(value"год""года""лет"); 

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

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±
    Цитата Сообщение от UnO Посмотреть сообщение
    PHP код:
    new _macros_new_num;
    #define PluralToText(%0,%1,%2,%3) \
        
    ((_macros_new_num = ((%100) >= 20 ? (%10) : %0)) == ? (%1) : (<= _macros_new_num <= ? (%2) : (%3)))
    //"новое уведомление"(1), "новых уведомления"(2-4), "новых уведомлений" 

    //
    PluralToText(value"год""года""лет"); 
    Можешь объяснить смысл всех этих проверок? Ато я просто скопирую, а сам ничего в макросах не пойму)

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от UnO Посмотреть сообщение
    PHP код:
    new _macros_new_num;
    #define PluralToText(%0,%1,%2,%3) \
        
    ((_macros_new_num = ((%100) >= 20 ? (%10) : %0)) == ? (%1) : (<= _macros_new_num <= ? (%2) : (%3))) 
    Для чего в макросе используется переменная "_macros_new_num"?
    P.S.: Вопрос с подвохом :)
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

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

    Статус
    Оффлайн
    Регистрация
    20.01.2018
    Сообщений
    52
    Репутация:
    7 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Для чего в макросе используется переменная "_macros_new_num"?
    P.S.: Вопрос с подвохом :)
    Чтобы два раза не считать одно и то же?
    В принципе, вот так тоже работать будет:
    PHP код:
    #define PluralToText(%0,%1,%2,%3) \
        
    ((((%100) >= 20 ? (%10) : %0)) == ? (%1) : (<= ((%100) >= 20 ? (%10) : %0) <= ? (%2) : (%3))) 
    - - - Добавлено - - -

    Цитата Сообщение от Steve_Stage Посмотреть сообщение
    Можешь объяснить смысл всех этих проверок? Ато я просто скопирую, а сам ничего в макросах не пойму)
    %0 - число, под которое склоняем
    %1, %2, %3 - готовые слова

    вот и подставь это в формулу и разбери тернарный оператор

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

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±
    Эти макросы ооочень сложные для меня, я не понимаю, почему делить с остатком на 100? Почему опендры либо сам %0, либо его вариация, поделенная с остатком на 10? Может я тупой, но в этом макросе я совершенно не вижу логику

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

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Вот, посмотри систему без макросов:
    https://github.com/Open-GTO/Open-GTO...declension.pwn

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

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±
    Сколько там бесполезных стоков, выходит макросы реально нужны, но я так и не понял, как работает логика? И еще там какой-то неизвестный мне Lang_GetPlayerText, которого нету в инете

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от UnO Посмотреть сообщение
    Чтобы два раза не считать одно и то же?
    Я ведь не просто так предупредил, что вопрос с подвохом...
    "%0" в любом случае считается 2 раза: сначала в "(%0 % 100)", а затем либо в "? (%0 % 10)", либо в ": %0". Это во-первых.

    Во-вторых, временная переменная нужна не столько для того, чтобы "два раза не считать одно и то же", сколько чтобы предотвратить неочевидную модификацию входных данных больше одного раза.
    Пример:
    1. Double_Func(x)
    2. return x + x;
    3.  
    4. #define Double_Macro(%0) \
    5.   ((%0) + (%0))
    6.  
    7. main()
    8. {
    9. new x = 10, y = 10;
    10. printf("Double_Func: %d", Double_Func(x++));
    11. printf("Double_Macro: %d", Double_Macro(y++));
    12. }

    При компиляции и запуске в консоль будет выведено:
    Код:
    Double_Func: 20
    Double_Macro: 21
    А всё потому, что при раскрытии макроса "y++" будет вычислено дважды и получится "10 + 11" вместо ожидаемого "10 + 10".




    Цитата Сообщение от ziggi Посмотреть сообщение
    Вот, посмотри систему без макросов:
    https://github.com/Open-GTO/Open-GTO...declension.pwn
    Возможно, ты захочешь добавить лицензию в отдельные файлы со своим кодом, чтобы другие тоже могли свободно воспользоваться ими?
    (В принципе, этим кодом и сейчас можно пользоваться, но только в некоммерческих целях, по основной лицензии Open-GTO. И я ни в коем случае ни к чему не принуждаю, просто хотел поделиться идеей. Кто знает, может быть тебе владельцы какого-то сервера уже платят за разрешение на коммерческое использование твоего кода :) )




    Цитата Сообщение от Steve_Stage Посмотреть сообщение
    Сколько там бесполезных стоков, выходит макросы реально нужны, но я так и не понял, как работает логика?
    Основная логика находится в Declension_GetWord(): https://github.com/Open-GTO/Open-GTO...on.pwn#L27-L46
    Попробую объяснить на пальцах.
    1. "num %= 100;" - это нужно потому, что через каждую сотню варицаии слова повторяются. Т.е.: один год => сто один год, два года => две тысячи четыреста два года
    2. Через каждые десятки варианты слова тоже повторяются: один год => двадцать один год, четыре года => сорок четыре года.
    НО: одиннадцать лет, двенадцать лет, тринадцать лет, четырнадцать лет, т.е. на 11-14 действует исключение из правила, и поэтому если просто сделать "num % 10" и сравнить результат с 1 и 2..4, то для 11..14 будет выдавать неправильный результат.
    Решение: вычислить остаток от деления на 10 (т.е. привести к диапазону от 0 до 9) только если число больше или равно 20.
    1. if (num >= 20) // либо "num > 19"
    2. num %= 10;

    В этом случае
    • Числа 0..9 уже находятся в нужном нам диапазоне.
    • Числа 10..19 будут оставлены без изменений.
    • Числа 20..99 будет приведены к диапазону 0..9.

    После этого остаётся только в switch сравнить num с 1 и 2..4, чтобы выбрать нужную форму слова.
    Как-то так.

    Цитата Сообщение от Steve_Stage Посмотреть сообщение
    И еще там какой-то неизвестный мне Lang_GetPlayerText, которого нету в инете
    Это из системы мультиязычности zlang: http://pro-pawn.ru/showthread.php?14265
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  10. #10
    Аватар для SteveStage
    Пользователь

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±
    Спасибо, Даниэль, но я сделал чуть попроще и понятнее для меня. Спасибо за разжевывание смысла этого стока и этого макроса!

 

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

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

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

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

Ваши права

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