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

    Статус
    Оффлайн
    Регистрация
    28.03.2013
    Адрес
    Владикавказ
    Сообщений
    16
    Репутация:
    10 ±

    Работаем с битами

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

    А теперь попробуем начать использовать их, на примере давайте заменим банальные лицензии. Например у нас их три - на лодку воздух и авто.

    Создаем нашу переменную в которой записаны биты.
    PHP код:
    new lics 0b000
    Как мы знаем 0 - false, то есть ложь; 1 - true, то есть истина. В нашем случае будет также - 0 есть лицензия, 1 - нету.

    Внимание! Биты как и массив начинаются с нулевого!

    Давайте попробуем присвоить значение лицензии на авто - 1
    Как мы это сделаем:
    PHP код:
    lics ^= (1<<0); 
    ^ - это оператор "Исключающее или", почему мы используем именно его? Потому-что если вы захотите инвертировать сразу несколько битов - он нам в этом поможет.
    И так, мы инвертируем первый бит справа налево, т.е

    Как было:
    PHP код:
    0b000 
    Как стало:
    PHP код:
    0b001 
    Окей, с этим разобрались.

    А если нам нужно присвоить сразу несколько значений, как быть?
    Решение:
    PHP код:
    lics ^= ((1<<0)|(1<<1)|(1<<2)); 
    (1<<0) мы присваиваем нулевому биту слева значение 1, инверсия.
    (1<<1) если вы ещё не поняли почему первая цифра 1 - мы сдвигаемся на один бит влево; 1 - инвертируем первый бит читая справа налево.
    (1<<2) тоже самое что и все выражения выше, только уже операция производится со вторым битом.

    Тем самым мы произвели инверсию битов. Т.е если у нас было 000, мы вывели 111. ( также и наоборот )

    Дальше идет проверка на лицензии.

    Например, узнаем есть ли у нас лицензия на автомобиль
    PHP код:
    if((lics & (1<<0)) == 0) return SendClientMessage(playerid,0xFF0000FF,"У вас нет лицензии на автомобиль"); 
    Поясняю, мы проверяем почти также, как и устанавливаем. Т.е на сдвигаем на один бит влево ( в проверке ) и проверяем нулевой бит справа налево. Если он не равен нулю, значит лицензия есть. == 1 ставить не рекомендую.

    PHP код:
    if((lics & (1<<1)) == 0) return SendClientMessage(playerid,0xFF0000FF,"У вас нет лицензии на воздушный транспорт"); 
    То же что и выше, только проверяем уже второй бит

    Как примерно это будет выглядеть в моде?:

    PHP код:
    new lics[MAX_PLAYERS];

    callback PlayerReg(playerid) { // callback - фаш коллбек присвоения данных при коннекте ( обнуление )
        
    lics[playerid] = 0b000;
    }

    CMD:givelicense(playerid,params[]) {
        if(
    sscanf(params,"u",params[0])) return SendClientMessage(playerid,-1,"/givelicense [id]");
        
    lics[params[0]] ^= (1<<0);
        
    SendClientMessage(playerid,-1, ((lics[params[0]] & (1<<0)) != 0) ? ("Лицензия на авто получена!") : ("Лицензия на авто изъята!"));
        return 
    true;

    p.s: Если хотите, можете юзать >> слева направо


    Также D_C предложил следующий варинт:

    В самом начале сделать перечисление, чтобы не париться с номерами лицензий:
    PHP код:
    enum
    {
        
    LICENSE_DRIVING 0,
        
    LICENSE_BOATING,
        
    LICENSE_PILOT
    }; 
    затем при сдвигах использовать элементы этого перечисления:

    PHP код:
    lics[targetid] |= (<< LICENSE_DRIVING); 



    Вариант Londlem'a:

    Также, чтобы не смещать каждый раз, лучше сделать смещение прямо в энумераторе.
    PHP код:
    enum(<<= 1)
    {
        
    LICENSE_DRIVING 1// 1
        
    LICENSE_BOATING// 2
        
    LICENSE_PILOT // 4
    }; 
    Далее просто используем битовый оператор или ( |= ) и название константы:
    PHP код:
    lics[targetid] |= LICENSE_DRIVING
    И проверять на наличие одной из лицензии почти также:
    PHP код:
    if((lics[targetid] & LICENSE_DRIVING) != 0)
        
    // code 
    Разницы почти никакой нет, разве что, не нужно каждый раз смещать, удобнее.



    Делаем сохранение \ загрузку ( MySQL ):
    Для этого уже мы будем присваивать не 0b000, а 0 ( тоже самое что и 000 )
    Мы будем загружать целое число также как и сохранять, а менять уже в нем биты.

    Я предлагаю вам создать в вашем массиве игроков переменную Licenses, дабы было удобнее.

    Загружаем:

    PHP код:
    Player[playerid][Licenses] = cache_get_field_content_int(0"licenses"connectionHandle); 
    Player - ваш массив игрока
    Licenses - наши лицензии
    "licenses" - поле в БД где хранится наша переменная
    connectionHandle - переменная вашего соединения

    Сохраняем:
    PHP код:
    new query[81+1]; // 81 на запрос; Одну ячейку отдаем машине
    mysql_format(connectionHandle,query,80,"UPDATE `accounts` SET `licenses` = '%i' WHERE `Name` = '%s'",Player[playerid][Licenses],name);
    mysql_tquery(connectionHandle,query,"",""); 
    accounts - ваша таблица с аккаунтами
    licenses - ваше поле в бд для сохранении нашей переменной
    name - переменная определяющая имя игрока. Я предлагаю использовать удобный вариант - в массив игрока добавляем массив Name, который будет равен макс.значению имени игрока (24), далее в OnPlayerConnect присваиваем переменной значение нашего имени, думаю вы поняли как это сделать. Ну и использовать можно как Player[playerid][Name], либо создать макрос #define Name(%0) Player[%0][Name]. Это удобно и к тому же не нужно лишний раз создавать эти ненужные переменные. И так, тут думаю все ясно, посылаем запрос в таблицу accounts с нашими параметрами.

    Такие пироги, легко и просто, не правда ли?






    Автор: georJik


    Тема будет дополняться...
    Последний раз редактировалось georJik; 23.07.2014 в 09:05.
    Lorem ipsum
    что это за хуйня?

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    1. Что означают "SCM" и "callback" ?
    2. Можно было в самом начале сделать перечисление, чтобы не париться с номерами лицензий:
      PHP код:
      enum
      {
          
      LICENSE_DRIVING 0,
          
      LICENSE_BOATING,
          
      LICENSE_PILOT
      }; 
      затем при сдвигах использовать элементы этого перечисления:
      PHP код:
      lics[targetid] |= (<< LICENSE_DRIVING); 
      Было бы куда более наглядно.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  3. 2 пользователя(ей) сказали cпасибо:
    georJik (21.07.2014) L0ndl3m (21.07.2014)
  4. #3
    Аватар для georJik
    Пользователь

    Статус
    Оффлайн
    Регистрация
    28.03.2013
    Адрес
    Владикавказ
    Сообщений
    16
    Репутация:
    10 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    1. Что означают "SCM" и "callback" ?
    2. Можно было в самом начале сделать перечисление, чтобы не париться с номерами лицензий:
      PHP код:
      enum
      {
          
      LICENSE_DRIVING 0,
          
      LICENSE_BOATING,
          
      LICENSE_PILOT
      }; 
      затем при сдвигах использовать элементы этого перечисления:
      PHP код:
      lics[targetid] |= (<< LICENSE_DRIVING); 
      Было бы куда более наглядно.
    Кому как удобнее, можно даже задефайнить как номер ячейки
    Lorem ipsum
    что это за хуйня?

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

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от georJik Посмотреть сообщение
    Кому как удобнее
    Это не удобство, а обычная практика при хранении данных в упакованном виде. Не держать же в голове кучу ID сдвигов для каждого случая.
    Потому, собсна, и предложил дополнить 1-й пост. Но, если не хотите - не дополняйте, дело ваше.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

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

    Статус
    Оффлайн
    Регистрация
    28.03.2013
    Адрес
    Владикавказ
    Сообщений
    16
    Репутация:
    10 ±
    Дополнил, подправил
    Lorem ipsum
    что это за хуйня?

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

    Статус
    Оффлайн
    Регистрация
    19.10.2013
    Адрес
    Ярославль
    Сообщений
    1,366
    Репутация:
    774 ±
    Также, чтобы не смещать каждый раз, лучше сделать смещение прямо в энумераторе.
    PHP код:
    enum(<<= 1)
    {
        
    LICENSE_DRIVING 1// 1
        
    LICENSE_BOATING// 2
        
    LICENSE_PILOT // 4
    }; 
    Далее просто используем битовый оператор или ( |= ) и название константы:
    PHP код:
    lics[targetid] |= LICENSE_DRIVING
    И проверять на наличие одной из лицензии почти также:
    PHP код:
    if((lics[targetid] & LICENSE_DRIVING) != 0)
        
    // code 
    Разницы почти никакой нет, разве что, не нужно каждый раз смещать, удобнее.
    Последний раз редактировалось L0ndl3m; 21.07.2014 в 23:46.

  8. 5 пользователя(ей) сказали cпасибо:
    Daniel_Cortez (22.07.2014) DeimoS (22.07.2014) MR_BEN (21.07.2014) Salvacore (22.07.2014) wAx (22.07.2014)
  9. #7
    Аватар для Salvacore
    Инжунер-погромист

    Статус
    Оффлайн
    Регистрация
    10.05.2013
    Адрес
    Аҧсуа бызшәа
    Сообщений
    2,271
    Репутация:
    418 ±
    Буду битмейкером.

  10. #8
    Аватар для Maranzalla
    Заблокирован

    Статус
    Оффлайн
    Регистрация
    25.04.2014
    Адрес
    Moscow
    Сообщений
    108
    Репутация:
    -1 ±
    Цитата Сообщение от georJik Посмотреть сообщение
    А теперь попробуем начать использовать их, на примере давайте заменим банальные лицензии. Например у нас их три - на лодку воздух и авто.

    Создаем нашу переменную в которой записаны биты.
    PHP код:
    new lics 0b000
    Как мы знаем 0 - false, то есть ложь; 1 - true, то есть истина. В нашем случае будет также - 0 есть лицензия, 1 - нету.
    Вот этот момент поподробнее можно?
    что такое первое 0
    второе b
    и с третьего по пятые 0

  11. #9
    Аватар для NewGreen
    Пользователь

    Статус
    Оффлайн
    Регистрация
    29.09.2014
    Сообщений
    61
    Репутация:
    44 ±
    Цитата Сообщение от Maranzalla Посмотреть сообщение
    Вот этот момент поподробнее можно?
    что такое первое 0
    второе b
    и с третьего по пятые 0
    Это инициализация переменой двоичным (бинарным) числом, b - binary, 0b - сообщает компилятору, что дальнейшее число будет представлено в двоичном виде, 000 - число в двоичном представлении.

  12. 2 пользователя(ей) сказали cпасибо:
    Maranzalla (19.03.2015) [ForD] (20.03.2015)
  13. #10
    Аватар для Maranzalla
    Заблокирован

    Статус
    Оффлайн
    Регистрация
    25.04.2014
    Адрес
    Moscow
    Сообщений
    108
    Репутация:
    -1 ±
    Какое максимальное количество бит можно использовать для переменной
    new param[MAX_PLAYERS char];?

 

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

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

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

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

Ваши права

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