[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


Messages In This Thread
Bit Flags - by RockFire - 16.03.2014, 17:46
Re: Bit Flags - by Dolby - 16.03.2014, 17:52
Re: Bit Flags - by RockFire - 16.03.2014, 17:58
Re: Bit Flags - by WLSF - 16.03.2014, 18:00
Re: Bit Flags - by shittt - 16.03.2014, 18:25
Respuesta: Bit Flags - by AlieN_ - 16.03.2014, 18:40
Re: Bit Flags - by RockFire - 16.03.2014, 18:45
Re: Bit Flags - by PT - 16.03.2014, 18:54
Re: Bit Flags - by rjjj - 16.03.2014, 20:02
Re: Bit Flags - by RockFire - 16.03.2014, 20:16

Forum Jump:


Users browsing this thread: 1 Guest(s)