[Tutorial] Bit Flags
#1

Bit Flags

Bit Flags nгo sгo nada mais e nada menos que valores binбrios, vocк pode criar 31 variбveis booleanas com uma ъnica variбvel.

Vocк precisa de uma noзгo bбsica de nъmeros binбrios, recomendo o seguinte tutorial:
https://sampforum.blast.hk/showthread.php?tid=177523


pawn Код:
new BitFlags;
Seria o mesmo que:
pawn Код:
new bool: Booleans[31];
Vocк precisa de um enumerador para facilmente distinguir os valores.
pawn Код:
enum (<<= 1)
{
    first_flag = 0b1,
    second_flag,
    third_flag
}
O "(<<= 1)" no exemplo acima deslocarб o valor da constante anterior (exceto a primeira) para a esquerda uma vez:
(Semelhante а notaзгo cientнfica que vocк deve ter aprendido em matemбtica)

Код:
0b1   << 1 = 0b10.
0b10  << 1 = 0b100.
0b100 << 1 = 0b1000.
Cada um desses bits representa uma potкncia de 2:
IMPORTANTE: Nesse exemplo o ^ й usado para representar potкncia.

Код:
2^0 = 1 = 0b1
2^1 = 2 = 0b10
2^2 = 4 = 0b100
pawn Код:
enum (<<= 1)
{
    PLAYER_CONNECTED = 0b1,
    PLAYER_HAS_VEHICLE,
    PLAYER_LIKES_STRAWBERRIES,
    PLAYER_HAS_DEGREE
}
new PlayerFlags[MAX_PLAYERS];
Ok, mas como eu uso isso?
Primeiro, vocк deve usar o operador lуgico OR (|) para dar um valor а sua flag.

Neste ponto sua variбvel estб nula.
pawn Код:
public OnPlayerConnect(playerid)
{
    PlayerFlags[playerid] |= PLAYER_CONNECTED;
    return 1;
}
Agora sua variбvel tem um valor:
0b1

pawn Код:
CMD:strawberries(playerid, params[])
{
    PlayerFlags[playerid] |= PLAYER_LIKES_STRAWBERRIES;
    return 1;
}
Assim quк o jogador digitar o comando /strawberries, ele "ligarб" a flag PLAYER_LIKES_STRAWBERRIES, correspondente ao terceiro bit, equivalente a 0b100.
Agora sua variбvel tem um valor diferente de antes:
0b101

Aqui vai uma dica (Pode lhe ajudar ou lhe atrapalhar dependendo do seu raciocнnio):
Inverta o 0b100.
0b001, certo?

Код:
   0b1
+  0b001
   -----
   0b101
Se isso lhe confundiu, apenas esqueзa.

Como eu consigo o valor de uma determinada flag?
Usando do operador lуgico AND (&) e comparando o resultado com a flag.
pawn Код:
CMD:strawberriesftw(playerid, params[])
{
    if((PlayerFlags[playerid] & PLAYER_LIKES_STRAWBERRIES) == PLAYER_LIKES_STRAWBERRIES)
        return SendClientMessage(playerid, -1, "STRAWBERRIES ARE WORTH MY TIME!!!!1111111111111");

    return 1;
}
E para comparar multiplos valores?
pawn Код:
CMD:strawberriesftw(playerid, params[])
{
    if((PlayerFlags[playerid] & (PLAYER_LIKES_STRAWBERRIES | PLAYER_CONNECTED)) == (PLAYER_LIKES_STRAWBERRIES | PLAYER_CONNECTED))
        return SendClientMessage(playerid, -1, "STRAWBERRIES ARE WORTH MY TIME!!!!1111111111111");

    return 1;
}
Este post explica isso melhor.

E para mudar o valor de 1 para 0 e vice-versa?
Isso й chamado de swap, e involve o uso do operador lуgico XOR (^)

pawn Код:
CMD:iambipolar(playerid, params[])
{
    PlayerFlags[playerid] ^= PLAYER_LIKES_STRAWBERRIES;

    return 1;
}
Vocк tambйm pode usar AND (&) em conjunto com o NOT (~)

pawn Код:
CMD:iambipolar(playerid, params[])
{
    PlayerFlags[playerid] &= ~PLAYER_LIKES_STRAWBERRIES;

    return 1;
}
Se vocк usasse o AND sem o NOT, ele iria "resetar" o valor de todas exceto o bit correspondido as outras flags, o NOT simplesmente vai inverter (e.g. 0b100 para 0b011).
Este post explica isso melhor.

Macros ъteis:
pawn Код:
#define BitFlag_Set(%0,%1) %0 |= %1
#define BitFlag_Clear(%0,%1) %0 &= ~%1
#define BitFlag_Get(%0,%1) (((%0) & (%1)) == (%1)))
#define BitFlag_Toggle(%0,%1) %0 ^= %1[/url]
Utilizaзгo:
Esse й um script que faz uso de Bit Flags.
Reply
#2

O intuito do tutorial й уtimo, porйm ficou um pouco confuso.

Seria interessante vocк explicar onde pode utilizar, etc.

Parabйns.
Reply
#3

Ninguйm gosta de ter vбrias bools no topo do seu gamemode quando vocк pode criar uma simples vбriavel e guardar todos os valores lб. Usando isso vocк pode poupar memуria, o mнnimo que seja.
Reply
#4

Й complicado Dolby, essa questгo do uso vai da criatividade de cada pessoa, se me lembro bem usei isso no iBits pra poder fazer a marcaзгo dos itens que eu usaria pra calcular.

Parabйns pelo tutorial, rock..
Reply
#5

Parabйns otimo tutorial
Reply
#6

ta voltando com samp dnv rock?lembro de jogar com vocк no nd...huasuashuahua...otimo tutorial,abrassos...
Reply
#7

Eu nгo parei de jogar, apenas havia perdido o interesse em programaзгo, aliбs sou um admin lб.
http://www.dawn-tdm.com/user/165-
Reply
#8

O Willian_Luigi ja me tinha falado disso uma vez.

Gostei do tutorial parabens.
Reply
#9

Й um tutorial decente, feliperch .



Eu nгo entendia essa tйcnica atй ler seu tutorial, sendo que no campo da programaзгo ela muitas vezes й necessбria para a manipulaзгo de bits, visto que o menor tamanho de dado que os computadores de hoje em dia internamente conseguem reconhecer equivale a 1 byte (8 bits).



Contudo, devo avisar que, enquanto fazia testes, percebi uma certa falha nesta linha do tutorial, que supostamente transformaria em 0 somente o bit relativo a IS_PLAYER_LOGGED:


pawn Код:
pFlags[playerid] &= IS_PLAYER_LOGGED;

De acordo com o tutorial, a constante IS_PLAYER_LOGGED de fato equivaleria а seguinte informaзгo de 32 bits :


pawn Код:
00000000000000000000000000000010


Se, por exemplo, a variбvel pFlags[playerid] armazenasse a seguinte informaзгo de 32 bits, que representaria o valor 1 para todas as constantes da enum:


pawn Код:
00000000000000000000000000001110

Entгo, com isto :


pawn Код:
pFlags[playerid] &= IS_PLAYER_LOGGED;

As informaзхes binбrias que citei seriam multiplicadas bit a bit entre si, resultando neste novo valor de pFlags[playerid]:


pawn Код:
00000000000000000000000000000010

Isso significa que o bit correspondente a IS_PLAYER_LOGGED seria mantido, enquanto todos os outros assumiriam o valor 0.



Por ser o objetivo justamente o inverso, ou seja, que o bit de IS_PLAYER_LOGGED torne-se 0 e todos os outros sejam mantidos, й que se costuma incluir uma operaзгo de negaзгo bit a bit no processo :


pawn Код:
pFlags[playerid] &= ~IS_PLAYER_LOGGED;

Bem, continue ajudando o fуrum e seus membros com seu diversificado conhecimento. Sem dъvidas й uma participaзгo de destaque.



Espero ter ajudado .
Reply
#10

Muito obrigado, rjjj

Eu nгo havia percebido isso antes, muito obrigado pela explicaзгo, vou editar meu erro.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)