Примечание: Важно отметить, что если, к примеру, у нас есть 1 = 0000 0000 0000 0000 0000 0000 0000 0001 и выполняя 1 << 32 мы получаем: 1 0000 0000 0000 0000 0000 0000 0000 0000, как видно 1 выходит за пределы. Поэтому при 32 игроках на сервере, мы не получим верную работоспособность. Для этого надо отнять 1. Вместо 1-32 у нас будет 0-31.
К примеру, вместо:
new bool: is_alive[33]
Запишем:
new bitsum_is_alive
Вместо:
if (is_alive[id])
{
}
Запишем:
if (bistum_is_alive & (1<<(id-1)))
{
}
Вместо:
is_alive[id] = true
is_alive[id] = false
Запишем:
bitsum_is_alive |= (1<<(id-1))
bitsum_is_alive &= ~(1<<(id-1))
Если рассматривать, к примеру, присвоение:
is_alive[id] = true
или как мы заменили:
bitsum_is_alive |= (1<<(id-1))
где id = 1 при bitsum_is_alive = 0000 0000 0000 0000 0000 0000 0000 0000, то есть игрок id = 1, первый на сервере.
Вычисления:
1. id-1 = 1-1 = 0
2. 1<<(id-1) = 1 << 0 =
0000 0000 0000 0000 0000 0000 0000 0001 << 0 = 0000 0000 0000 0000 0000 0000 0000 0001
3. bitsum_is_alive | (1<<(id-1)) =
0000 0000 0000 0000 0000 0000 0000 0000
|
0000 0000 0000 0000 0000 0000 0000 0001
=
0000 0000 0000 0000 0000 0000 0000 0001
4. bitsum_is_alive = bitsum_is_alive | (1<<(id-1)) = 0000 0000 0000 0000 0000 0000 0000 0001
А если допустить, к примеру, что bitsum_is_alive = 0000 0000 0000 0010 0100 0000 0100 0001, что говорит нам о том, что игроки у которых id равно 1, 7, 15, 18 - живы, так как у них бит равен 1, отсчет битов ведется с конца. То присвоение игроку id = 7 (выделенный красный бит) статуса мертвый (бит в 0), будет происходить след. образом (как мы заменяли код выше):
bitsum_is_alive &= ~(1<<(id-1))
Вычисления:
1. id-1 = 7-1 = 6
2. 1<<(id-1) = 1<<6 =
0000 0000 0000 0000 0000 0000 0000 0001 << 6 = 0000 0000 0000 0000 0000 0000 0100 0000
3. ~(1<<(id-1)) = 1111 1111 1111 1111 1111 1111 1011 1111
4. bitsum_is_alive & ~(1<<(id-1)) =
0000 0000 0000 0010 0100 0000 0100 0001
&
1111 1111 1111 1111 1111 1111 1011 1111
=
0000 0000 0000 0010 0100 0000 0000 0001
5. bitsum_is_alive = bitsum_is_alive & ~(1<<(id-1)) = 0000 0000 0000 0010 0100 0000 0000 0001.
Мы получили bitsum_is_alive = 0000 0000 0000 0010 0100 0000 0000 0001
Можно ли как-то оптимизировать работу?
Можно сделать stock функцию:
stock is_user_alive(id)
{
return (bistum_is_alive & (1<<(id-1))) ? 1 : 0
}
Или макрос:
#define is_user_alive(%1) (bistum_is_alive & (1 << (%1-1))) ? 1 : 0
Автор статьи: DJ_WEST